无法为使用 maven-shaded-plugin 创建的 jar 获取条目 BOOT-INF/lib 的嵌套存档

Posted

技术标签:

【中文标题】无法为使用 maven-shaded-plugin 创建的 jar 获取条目 BOOT-INF/lib 的嵌套存档【英文标题】:Failed to get nested archive for entry BOOT-INF/lib for jar created with maven-shaded-plugin 【发布时间】:2019-08-10 13:14:56 【问题描述】:

我正在使用 spring-boot-maven-plugin:2.1.0.RELEASE 来打包我的主线应用程序。此应用程序已打包所有常见的依赖项等

在一个单独的项目中,我正在使用 maven-shade-plugin:2.4.3 构建一个阴影 jar,并使用 org.codehaus.mojo:truezip-maven-plugin 在 BOOT-INF/lib 目录下注入我的 Spring Boot 应用程序:1.1。现在,当我启动我的 spring-boot 应用程序时,我遇到了以下异常;

ingester_1         | Listening for transport dt_socket at address: 40500
ingester_1         | Exception in thread "main" java.lang.IllegalStateException: Failed to get nested archive for entry BOOT-INF/lib/ms-holdings-package-docker-DEV.0.0-SNAPSHOT.jar
ingester_1         |    at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:108)
ingester_1         |    at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:86)
ingester_1         |    at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:70)
ingester_1         |    at org.springframework.boot.loader.Launcher.launch(Launcher.java:49)
ingester_1         |    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
ingester_1         | Caused by: java.io.IOException: Unable to open nested jar file 'BOOT-INF/lib/ms-holdings-package-docker-DEV.0.0-SNAPSHOT.jar'
ingester_1         |    at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:256)
ingester_1         |    at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:241)
ingester_1         |    at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:103)
ingester_1         |    ... 4 more
ingester_1         | Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/ms-holdings-package-docker-DEV.0.0-SNAPSHOT.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
ingester_1         |    at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:284)
ingester_1         |    at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:264)
ingester_1         |    at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:252)
ingester_1         |    ... 6 more

我试图复制 BOOT-INF/lib 中的 jar,直接取出 maven-truezip-plugin,但还是一样。无论如何我可以解决这个问题吗?或解决方法?

【问题讨论】:

仅供参考,我使用jar -xvf 解压有问题的jar 并使用jar -cfm0M... 重新打包,将jar 放回spring-boot 应用程序,但没有用。我现在怀疑 spring-boot 有问题! 正如 discussed on GitHub 一样,您添加的 jar 存储不正确。您是否尝试过进行配置以使其在您的应用程序 jar 中的条目不被压缩?您可以阅读有关此要求的更多信息in the documentation。 @AndyWilkinsona 感谢您的链接。这意味着我不能使用 Spring Boot Loader 并且必须使用替代方案!如果文档显示了另一种包装样式示例以及如何将其与 Spring Boot 包装进行比较以使其真正变得简单易用,那将对其他人有所帮助。 【参考方案1】:

在构建 jar 时将其添加到插件配置中。

           <archiverConfig>
                <compress>false</compress>
            </archiverConfig>

【讨论】:

请不要多次发布相同的答案,因为您有here、here 和here。【参考方案2】:

为我们修复,同样的失败消息,是只使用 spring-boot-maven-plugin(它为您创建一个可运行的 jar),而不是使用 shade 插件并从该 jar 运行它。

【讨论】:

【参考方案3】:

可以解决问题,在我的 maven 包构建中;

1) Invoked ANT to unzip the released template SPRING-BOOT-app.jar
2) Unzip and repackage additional shaded artefact from the project
3) Copy repackaged artefact under BOOT-INF/lib
4) Repackage SPRING-BOOT-app.jar

我的 pom 现在有以下附加步骤;

pom.xml

    <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>repackage-app</id>
            <phase>package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target name="repack-app">
                    <property name="workDirectory" value="$project.build.directory/app-repack" />
                    <property name="sourceArtifact" value="$project.build.directory/SPRING-BOOT-app.jar" />
                    <property name="appendWith" value="$project.build.directory/$project.artifactId-$project.version.jar" /> 
                    <ant antfile="$packager.utilities.directory/build.xml"> 
                        <target name="append-and-repack-spring-boot-artiafact" />
                    </ant>
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

build.xml

    <?xml version="1.0" encoding="UTF-8"?>
<project name="utilities" basedir=".">

    <!-- Repack and append artifact to Spring Boot App -->
    <target name="append-and-repack-spring-boot-artiafact">

        <!-- Clean -->
        <delete dir="$workDirectory" failonerror="false"/>
        <mkdir dir="$workDirectory" />

        <!-- Copy the original files -->
        <copy file="$sourceArtifact" todir="$workDirectory"/>
        <copy file="$appendWith" todir="$workDirectory" />

        <!-- Get basename -->
        <basename property="sourceArtifactName" file="$sourceArtifact" />
        <basename property="appendArtifactName" file="$appendWith" />

        <!-- repackage and append -->
        <repack-jar artifact="$appendArtifactName" reworkOutputDir="$workDirectory/repackaged" />
        <append artifact="$sourceArtifactName" appendFrom="$workDirectory/repackaged" location="BOOT-INF/lib" />

    </target>

    <!-- Repackage a single jar -->
    <macrodef name="repack-jar">
        <attribute name="artifact" />
        <attribute name="reworkOutputDir" />
        <sequential>
            <echo
                message="-------------- Repackaging @artifact --------------" />
            <!-- Unpack and delete jar -->
            <unzip dest="$workDirectory/tmp" src="$workDirectory/@artifact" />
            <delete file="$workDirectory/@artifact" />

            <!-- Package jar -->
            <jar manifest="$workDirectory/tmp/META-INF/MANIFEST.MF"
                compress="false" basedir="$workDirectory/tmp"
                destfile="@reworkOutputDir/@artifact" />
            <delete dir="$workDirectory/tmp" />
        </sequential>
    </macrodef>

    <!-- Append artifact to jar -->
    <macrodef name="append">
        <attribute name="artifact" />
        <attribute name="appendFrom" />
        <attribute name="location" />
        <sequential>
            <echo
                message="-------------- Unpacking @artifact --------------" />
            <!-- Unpack and delete jar -->
            <unzip dest="$workDirectory/tmp" src="$workDirectory/@artifact" />
            <delete file="$workDirectory/@artifact" />

            <copy todir="$workDirectory/tmp/@location" overwrite="true" force="true">
                <fileset dir="@appendFrom" includes="*.jar" />
            </copy>

            <!-- Package jar -->
            <jar manifest="$workDirectory/tmp/META-INF/MANIFEST.MF"
                compress="false" basedir="$workDirectory/tmp"
                destfile="$workDirectory/@artifact" />
            <delete dir="$workDirectory/tmp" />
        </sequential>
    </macrodef>
</project>

注意:请勿使用 7Zip/Winrar 或任何其他压缩工具打开您计划部署的 Spring Boot 应用程序。它会更新压缩偏移(或其他东西)并且应用程序会失败。只是不要触摸人工制品,复制并检查!

【讨论】:

以上是关于无法为使用 maven-shaded-plugin 创建的 jar 获取条目 BOOT-INF/lib 的嵌套存档的主要内容,如果未能解决你的问题,请参考以下文章

错误:无法为使用 PEP 517 且无法直接安装的密码学构建***

无法使用类型为 '(Codable.Type?

打印机无法使用 原因为admin

使用下标时出错:无法使用类型索引为类型值下标...

错误:无法为使用 PEP 517 且无法直接安装的 Kivy 构建***

无法使用类型为“()”的参数列表为类型“Int”调用初始化程序