📜 ⬆️ ⬇️

We speed up the time of assembly and delivery of java web applications

Tltd


  1. removed jar from project build
  2. replaced it with a tasky, which is 7 times faster


Details and result under the cut.


about the project


A java web service that pushes rest api and websockets outside , and inside it is able to go to distributed database and distributed cache .


The project uses embedded jetty for start, it is started through public status void method .


It is delivered to the server as a fat jar and is launched via java -jar myapp.jar app.yaml


We profile


Gradle is a great tool that a profiler gives out of the box. Run the build with the --profile parameter and wait for the result.


 ./gradlew clean build --profile 

I think the result in commenting does not need:



We study the problem


First of all, I decided to see how the fat jar is being created:


 jar { manifest { attributes "Main-Class": "com.baeldung.fatjar.Application" } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } 

Register the class with the main method in the manifest and unpack the jar dependencies in the root jar folder of the archive.


This can be checked by unpacking jar unzip myapp.jar and viewing the tree of the current tree . folder tree .


It is not surprising that it is slow; many small files need to be unpacked first and then back packaged.


We optimize


Next, I tried to google a faster way to create a jar file.


I tried the gradle plugins:


gradle-fatjar-plugin - no longer supported
shadow - managed to collect them, but he uses the same method as above, so it did not increase in speed
gradle-one-jar - could not run at all, to be honest, maybe you just needed to spend more time


Then I got an idea, I can even say a challenge. And how to run applications without jar? I just had the unpacked archive, in order to try this.


It turned out not difficult:


 java -cp . com.example.Main app.yml 

The project started up perfectly, picked up the necessary config.


The -cp parameter is a classpath that tells the java process where all the classes of the project are located.


It turns out, the project can live without jar? Using a little help from the gradle community, I got a task that creates an exploded jar version:


 task explodedJar(type: Copy) { with jar into "${buildDir}/exploded" into('lib') { from configurations.runtimeClasspath } } jar.enabled = false assemble.dependsOn explodedJar 

Task


  1. puts all classes and resources in the exploded folder
  2. puts all dependency runtime in the lib folder
  3. add explodedJar and exclude jar task from ./gradle build

Run again


 ./gradlew build --profile 

Enjoying the result


I think comments are not needed here again.



It may still be worth duplicating the histogram from the beginning of the article, but I will not do that.


But how to deploy?


In order not to make this article very long, just leave one command to copy the project to the server:


 rsync --delete -r build/exploded api.example.com:/opt/myapp 

Total



')

Source: https://habr.com/ru/post/351636/


All Articles