'SpringBoot fully executable jar without dependencies inside
NOTE: Please, before marking this question as a duplicate make sure you know the difference between executable JAR and fully executable SpringBoot JAR.
The official Spring Boot documentation describes how to build fully executable JAR. Then generated JAR file can be linked from /etc/init.d/ and started/stopped/restarted/statused as a normal unix service without additional scripts or tools like JSVC.
But the generated JAR contains all libraries and can be big enough in size (in my case 70Mb+).
I want to generate such fully executable JAR without libraries, but then to be able to run it as SystemV service on Linux and link external libraries (JARs) somehow.
UPDATE
I want to reduce the artifact size in order to speed up deploy->test->fix cycle. Sometimes I'm working via mobile network and big file size can decrease my job speed dramatically.
In case there is no a simple configuration property or a profile or a command line option I would use a kind of hack.
At the beginning, I can generate a build containing all dependencies. Then I can unzip it and move all libraries to a special folder.
Then I need to pack it again as fully executable somehow and run with pointing to the folder with libraries.
I don't think this can be done with jar utility because file utility recognizes fully executable jar as data
$ file fully-executable.jar
file fully-executable: data
unlike the usual jar
$ file usual.jar
usual.jar: Java Jar file data (zip)
Solution 1:[1]
I can use this setting to create spring boot jar without dependency jars.
Copy dependency jars to dist/lib
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/dist/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Specify 'lib' as classpath prefix, so MAINFEST.MF will be created like this:
Class-Path:lib/httpcore-nio-4.4.14.jar lib/guava-24.1.1-jre.jar...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.xxx.MyMainClass</mainClass>
</manifest>
</archive>
<outputDirectory>${project.build.directory}/dist</outputDirectory>
</configuration>
</plugin>
Let spring boot plugin includes dependency which is not existing, will cause spring boot jar exclude all dependencies.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<layout>ZIP</layout>
<includes>
<include>
<groupId>not-exist-in-my-project</groupId>
<artifactId>not-exist-in-my-project</artifactId>
</include>
</includes>
<outputDirectory>${project.build.directory}/dist</outputDirectory>
</configuration>
</plugin>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | markhuang1994 |
