SpringBoot完全可执行的jar,内部没有依赖

SpringBoot fully executable jar without dependencies inside

注意:请在将此问题标记为重复之前确保您知道 可执行 JARfully executable SpringBoot JAR.

之间的区别

The official Spring Boot documentation 描述了如何构建完全 可执行 JAR。然后生成的 JAR 文件可以从 /etc/init.d/ 和 started/stopped/restarted/statused link 编辑为普通的 unix 服务,无需额外的脚本或工具,如 JSVC。

但是生成的 JAR 包含所有库并且大小足够大(在我的例子中是 70Mb+)。

我想生成这样的 完全 不带库的可执行 JAR,但随后能够 运行 它作为 Linux 和 [= 上的 SystemV 服务49=] 外部库 (JAR) 不知何故。

更新

我想减小工件大小以加快部署->测试->修复周期。有时我通过移动网络工作,大文件会大大降低我的工作速度。

如果没有简单的配置 属性 或配置文件或命令行选项,我会使用一种 hack。

一开始,我可以生成一个包含所有依赖项的构建。 然后我可以解压缩它并将所有库移动到一个特殊的文件夹中。

然后我需要以某种方式将其再次打包为完全可执行文件并 运行 指向包含库的文件夹。

我不认为这可以用 jar 实用程序来完成,因为 file 实用程序将完全可执行的 jar 识别为 data

$ file fully-executable.jar
file fully-executable: data

不同于通常的罐子

$ file usual.jar
usual.jar: Java Jar file data (zip)

您可能要考虑使用 Spring Boot Thin Launcher。它使用您的应用程序代码创建一个 jar 文件,但它的依赖项 none。它添加了一个特殊的瘦启动器,它知道如何在执行 jar 时从远程 Maven 存储库或从本地缓存解析应用程序的依赖性。根据您想要执行的操作的描述,您将使用本地缓存选项。

配置 Spring Boot 的 Maven 插件以生成使用瘦启动器的完全可执行的 jar,如下所示:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot.experimental</groupId>
                    <artifactId>spring-boot-thin-layout</artifactId>
                    <version>1.0.3.RELEASE</version>
                </dependency>
            </dependencies>
            <configuration>
                <executable>true</executable>
            </configuration>
        </plugin>
    </plugins>
</build>

我可以使用此设置创建 spring 没有依赖 jar 的启动 jar。

将依赖 jar 复制到 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>

将 'lib' 指定为类路径前缀,因此 MAINFEST.MF 将像这样创建:

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>

让 spring 引导插件包含不存在的依赖项,将导致 spring 引导 jar 排除所有依赖项。

<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>