我的java程序被打包在一个jar文件中,并使用了一个外部jar库,bouncy castle。我的代码编译良好,但运行jar会导致以下错误:

java.lang.SecurityException: Manifest主属性的签名文件摘要无效

我在谷歌上搜索了一个多小时,想要找到一个解释,但几乎没有什么价值。如果有人看到这个错误之前,可以提供一些帮助,我将不胜感激。


当前回答

对于那些在尝试使用maven-shade-plugin创建阴影超级jar时遇到此错误的人,解决方案是通过在插件配置中添加以下行来排除清单签名文件:

<configuration>
    <filters>
        <filter>
            <artifact>*:*</artifact>
            <excludes>
                <exclude>META-INF/*.SF</exclude>
                <exclude>META-INF/*.DSA</exclude>
                <exclude>META-INF/*.RSA</exclude>
            </excludes>
        </filter>
    </filters>
    <!-- Additional configuration. -->
</configuration>

其他回答

有可能是两个不同的签名者搞砸了java思维。

尝试从jar中删除META-INF文件夹,再次添加清单和签名jar,它帮助了我:http://jehy.ru/articles/2013/12/13/invalid-signature-file-digest-for-manifest-main-attributes/

我也遇到过类似的问题。原因是我使用的JDK的JRE与Windows系统中的默认JRE不同。

使用正确的java.exe解决了我的问题。

假设您使用ant构建jar文件,您可以指示ant去掉META-INF目录。这是我的蚂蚁目标的简化版本:

<jar destfile="app.jar" basedir="${classes.dir}">
    <zipfileset excludes="META-INF/**/*" src="${lib.dir}/bcprov-jdk16-145.jar"></zipfileset>
    <manifest>
        <attribute name="Main-Class" value="app.Main"/>
    </manifest>
</jar>

我也遇到过同样的问题,经过参考,它的工作原理如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.1</version>
    <configuration>
        <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
            </configuration>
        </execution>
    </executions>
</plugin>

有些依赖项可能是带符号的jarfile。当您将它们全部组合到一个大的jarfile中时,相应的签名文件仍然存在,并且不再与“大的组合”jarfile匹配,因此运行时停止认为jar文件已被篡改(它…可以这么说)。

假设您正在使用ant,可以通过从jarfile依赖项中删除签名文件来解决这个问题。不幸的是,在ant中不可能一步到位。

但是,我能够在Ant中分两步实现这个功能,而不需要具体地命名每个jarfile依赖项,通过使用:

<target name="jar" depends="compile" description="Create one big jarfile.">
    <jar jarfile="${output.dir}/deps.jar">
        <zipgroupfileset dir="jars">
            <include name="**/*.jar" />
        </zipgroupfileset>
    </jar>
    <sleep seconds="1" />
    <jar jarfile="${output.dir}/myjar.jar" basedir="${classes.dir}">
        <zipfileset src="${output.dir}/deps.jar" excludes="META-INF/*.SF" />
        <manifest>
            <attribute name="Main-Class" value="com.mycompany.MyMain" />
        </manifest>
    </jar>
</target>

sleep元素的作用是防止将来出现关于修改日期的文件的错误。

我在链接线程中发现的其他变化并不适合我。