我的java程序打包在jar文件中,并使用外部jar库(充气城堡)。我的代码可以正常编译,但是运行jar会导致以下错误:

线程“ main”中的异常java.lang.SecurityException:清单主要属性的无效签名文件摘要

我在Google上搜索了一个多小时,一直在寻找解释,却发现价值不高。如果有人以前曾见过此错误并可以提供帮助,则我有义务。

评论

您是否要签名自己的罐子?如果是这样,您打算如何签名?

不,至少我不认为我是。 Xcode可能试图自行对其进行签名,但是似乎没有任何设置可以将其关闭。

不要忘记检查包含已实现接口的jar是否也已签名!

#1 楼

此处列出的解决方案可能提供了一个指针。


清单主要属性的无效签名文件摘要


底线:


最好保持官方jar不变,而只是将其作为依赖文件添加到您的
应用jar文件的清单文件中。


评论


我将如何在清单文件中反映出来?我以前从未编辑过。我正在使用Xcode,通用约定是将外部jar库放在myproject / lib目录中以进行包含,这就是我正在做的事情。

–user123003
09年6月16日下午4:35

@ user123003 ..与Intelli-J一样

– StartupGuy
2014年7月5日在2:56



不幸的是,我们中的一些人使用诸如“ maven shade plugin”之类的东西,因此在这些情况下包括原始jar的逐字记录副本并不容易...

–rogerdpack
15年6月11日在18:26

无耻的插头在这个网站上回答:stackoverflow.com/a/30922181/448779

–foo
17年6月21日在19:35

那maven-assembly-plugin呢?它解决了我的情况

– jhenya-d
18年5月22日在12:30

#2 楼

对于那些尝试使用maven-shade-plugin创建带阴影的uber-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>
 


评论


我在uber-jar中使用了这种方法,效果很好。在maven.apache.org/plugins/maven-shade-plugin/examples/…中有一个完整的POM示例,其中显示了此方法可过滤包含的文件。

–杜德利先生
2011-09-28 13:28

我很想开始一个全新的话题-但由于它在Google的搜索结果中排名第一-似乎很容易将其保留在这里。此处列出的行在我正在使用的POM文件中-运行应用程序时仍然出现安全错误。正如预期的那样,它构建良好-并且当不使用Uber jar时当然可以运行良好。尽管这当然是一个选择-将它们分开放置-如果您想要一个Uber Jar并不能解决问题。

–加文·鲍曼尼斯(Gavin Baumanis)
16年5月17日在9:19

这对我有用,但是...为什么我们必须忽略签名文件?我确定签名清单是有原因的。

–杰里尔·库克(Jeryl Cook)
17年5月15日在21:23

完成上述操作后,请确保执行“ mvn clean”!

– codeinjuice
18年8月27日在19:26

@JerylCook签名文件在那里表明该jar的内容包含这些文件。制作uber jar时,您要向jar添加更多文件,因此签名不正确。如果您确实需要,可以重新签名新的jar,但是当然可以使用您的签名,而不是旧的签名。或者,您不能分发uber jar,而是将已签名的jar作为单独的文件包含在内,但是这样做首先违反了uber jar的目的。

–LadyCailin
19年1月22日在12:45

#3 楼

对于使用gradle并尝试创建和使用胖子的人,以下语法可能会有所帮助。

jar {
    doFirst {
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
}


评论


这只是基本上排除了META-INF目录中所有扩展名为.RSA,.SF或.DSA的文件。

– Keith P
2013年11月12日14:42

对jar文件进行签名会在META-INF下添加这些文件,但是当包含它们时,签名将不再与jar内容一致。因此删除它们可以避免签名不匹配。

– Peter N. Steinmetz
2014年4月4日在23:54

严格地在gradle中使用胖子罐也有一个类似的问题-stackoverflow.com/questions/4871656/…

– TomaszSętkowski
16年4月6日在18:45

这对我不起作用。我必须将排除项放到我的fatJar任务中,该任务具有该configuration.compile.collect命令。见stackoverflow.com/a/31426413/103412

– Torsten
16年5月10日在8:50

这也解决了错误错误:无法找到或加载主类App由:java.lang.ClassNotFoundException:App

– vonox7
19年11月18日在17:22

#4 楼

请使用以下命令

zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'


评论


谢谢,我在intellij 14中遇到了这个问题,您的解决方案对我有用!

– Mohamad Kouhi Moghadam
16-10-27在10:50

谢谢您在Windows中为我工作。刚刚用7zip打开了jar,删除了.SF文件。我没有任何要删除的.RSA文件

– candino
17 Mar 22 '17在8:44

哇,我能说这个解决方案很棒吗(我在此过程中学到了非常强大的知识!)这需要更多的支持。

– Dylan_Larkin
17年12月6日在18:55

我同意@Dylan_Larkin的评论,这就是为我解决的问题。

–Felipe Valdes
18年11月24日在17:40

应该是zip -d yourjar.jar'META-INF / *。SF''META-INF / *。RSA''META-INF / * DSA'

– StefanMK
11月3日16:46

#5 楼

您的某些依赖项可能是签名的jarfile。当您将它们全部组合到一个大的jar文件中时,相应的签名文件仍然存在,并且不再与“大组合的” jar文件匹配,因此运行时会停止运行,以为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元素应该可以防止以后带有修改日期的文件出现错误。
我在链接线程中发现的其他变化对我不起作用。

评论


可以使用另一种方法来指定您的jar,一步来做:

– DieterDP
13年4月16日在12:13



#6 楼

使用IntelliJ IDEA 14.01时出现此问题。

我可以通过以下方法修复它:

文件->项目结构->添加新(工件)-> jar->来自依赖于创建Jar的模块模块窗口:

选择主类

库中的JAR文件
选择复制到输出目录并通过清单链接

评论


是否可以将依赖的jar放入目标jar?

–coder.chenzhi
17年6月28日在4:29

#7 楼

安全性已经是一个艰巨的话题,但是令我失望的是,最受欢迎的解决方案是删除安全性签名。 JCE需要这些签名。 Maven阴影会爆炸BouncyCastle jar文件,该文件会将签名放入META-INF,但是BouncyCastle签名对于新的uber-jar无效(仅对BC jar),这就是导致此线程中的Invalid签名错误的原因。

是的,确实排除或删除@ruhsuzbaykus建议的签名确实可以使原始错误消失,但它也可能导致新的,隐秘的错误:

java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available


通过明确指定在哪里可以找到这样的算法:

SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");


我能够得到另一个错误:

java.security.NoSuchProviderException: JCE cannot authenticate the provider BC


JCE无法对提供程序进行身份验证,因为我们已经按照同一线程中其他地方的建议删除了加密签名。

我找到的解决方案是使用jar-in-jar方法将BouncyCastle签名保留在单个可执行jar中的可执行打包程序插件。


UPDATE:

另一种方法执行此操作(更正一种方法?)是使用Maven Jar签名者。这使您可以继续使用Maven阴影而不会出现安全错误。但是,您必须具有代码签名证书(Oracle建议搜索“ Java代码签名证书”)。 POM配置看起来像这样:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>org.bouncycastle:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>your.class.here</mainClass>
                    </transformer>
                </transformers>
                <shadedArtifactAttached>true</shadedArtifactAttached>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <version>1.4</version>
    <executions>
        <execution>
            <id>sign</id>
            <goals>
                <goal>sign</goal>
            </goals>
        </execution>
        <execution>
            <id>verify</id>
            <goals>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <keystore>/path/to/myKeystore</keystore>
        <alias>myfirstkey</alias>
        <storepass>111111</storepass>
        <keypass>111111</keypass>
    </configuration>
</plugin>


不,无法让JCE识别自签名证书,因此,如果需要保留BouncyCastle证书,您必须使用jar-in-jar插件或获得JCE证书。

评论


即使工作量很大,这绝对是正确的方法。感谢您详细指出使用批准答案的注意事项。您知道JCE证书是否必须由Sun签名吗?还是可以

–WiteCastle
17-10-18在15:03

有第三方可以颁发代码签名证书。搜索“ Java代码签名证书”以查看选项。

– MattW
17-10-19在15:34

您,先生,我过得愉快!

– socona
18年2月28日在10:51

对我有帮助。该库中有一些我不使用的文件,所以除了它们可以帮助我处理fat-jar文件

–塞多林
19/12/25在16:24

#8 楼

在引用某处后,我遇到了同样的问题,它的工作方式如下所示:

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


评论


这很快解决了我的问题!为了完整起见,这应该放在maven-shade-plugin标记中。

–库泽科
19年3月20日在16:00

@Kuzeko用您的建议更新了答案。谢谢

–m.nguyen ntt
19年3月21日在1:57

谢谢解决了我部署Java无服务器的问题

– Krismorte
6月19日19:55

#9 楼

假设您使用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>


评论


我应该在哪里添加这些行?

– Addi.Star
19/09/21在10:33

#10 楼

我最近开始在项目中使用IntelliJ。但是,我的一些同事仍然在同一项目上使用Eclipse。今天,在执行由IntelliJ创建的jar文件后,我遇到了同样的错误。尽管这里的所有解决方案都在谈论几乎同一件事,但它们都不适合我(可能是因为我不使用ANT,maven build给我带来了其他错误,这些错误使我引用了http://cwiki.apache.org/ confluence / display / MAVEN / MojoExecutionException,而且我自己也搞不清楚已签名的罐子是什么!) >
猜猜我的jar文件中删除了什么?!

zip -d demoSampler.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'


问题似乎与某些与eclipse相关的文件有关。

#11 楼

创建胖jar时,在gradle中遇到了相同的问题,使用排除行更新build.gradle文件更正了该问题。

jar {
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
    manifest {
        attributes 'Main-Class': 'com.test.Main'
    }
}


评论


我调试了几天,这解决了我的胖子问题。

– sysuser
19年11月7日,0:40

我调试的方法是将胖子放在jmeter lib目录中。如果您在lib / ext中有问题的jar,这个问题就不会很明显了,而是会出现类似stackoverflow.com/questions/37624187/的错误。

– sysuser
19年11月7日,0:57

排除'META-INF / *。RSA','META-INF / *。SF','META-INF / *。DSA'丢失了,某些依赖的jar导致了问题

– Nirbhay Mishra
4月24日5:49

#12 楼

如果您使用gradle,这是一个完整的farJar任务:

version = '1.0'
//create a single Jar with all dependencies
task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',  
            'Implementation-Version': version,
            'Main-Class': 'com.example.main'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
    with jar
}


#13 楼

将新jar中的META-INF文件夹与旧jar进行比较(在添加新库之前)。有可能会有新文件。如果是,则可以将其删除。应该会有所帮助。

999michal

#14 楼

一种策略是使用ANT简化从每个Jar文件中删除签名的过程。它将执行以下步骤:


将MANIFEST.MF复制到临时文件中
从临时文件中删除Name和SHA条目
创建临时文件带有临时清单的Jar文件
删除临时清单
将带有临时清单的Jar文件交换为临时文件

这是一个ANT macrodef在做的工作:

<macrodef name="unsignjar" description="To unsign a specific Jar file">
    <attribute name="jarfile" 
        description="The jar file to unsign" />
    <sequential>
<!-- Copying to the temporary manifest file -->
        <copy toFile="@{jarFile}_MANIFEST.tmp">
            <resources>
                <zipentry zipfile="@{jarFile}" name="META-INF/MANIFEST.MF"/>
            </resources>
        </copy>
<!-- Removing the Name and SHA entries from the temporary file -->
        <replaceregexp file="@{jarFile}_MANIFEST.tmp" match="\nName:(.+?)\nSH" replace="SH" flags="gis" byline="false"/>
        <replaceregexp file="@{jarFile}_MANIFEST.tmp" match="SHA(.*)" replace="" flags="gis" byline="false"/>
<!-- Creating a temporary Jar file with the temporary manifest -->
        <jar jarfile="@{jarFile}.tmp"
            manifest="@{jarFile}_MANIFEST.tmp">
            <zipfileset src="@{jarFile}">
                <include name="**"/>
                <exclude name="META-INF/*.SF"/>
                <exclude name="META-INF/*.DSA"/>
                <exclude name="META-INF/*.RSA"/>
            </zipfileset>
        </jar>
<!-- Removing the temporary manifest -->
        <delete file="@{jarFile}_MANIFEST.tmp" />
<!-- Swapping the original Jar file with the temporary one -->
        <move file="@{jarFile}.tmp"
              tofile="@{jarFile}"
              overwrite="true" />
</sequential>


`

然后可以在ANT任务中以这种方式调用定义:

<target name="unsignJar">
    <unsignjar jarFile="org.test.myjartounsign.jar" />
</target>


#15 楼


错误:发生了JNI错误,请检查您的安装并重试。
线程“主”中的异常java.lang.SecurityException:清单主要属性的无效签名文件摘要在Sun出现。 security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:314)
在sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:268)
在java.util.jar.JarVerifier.processEntry( JarVerifier.java:316)
at java.util.jar.JarVerifier.update(JarVerifier.java:228)
at java.util.jar.JarFile.initializeVerifier(JarFile.java:383)
在sun.misc.URLClassPath $ JarLoader $ 2.getInputStream(URLClassPath.java:977)在java.util.jar.JarFile.getInputStream(JarFile.java:450)
在sun.misc。在sun.misc.Resource.getByteBuffer(Resource.java:160)处的Resource.cachedInputStream(Resource.java:77)
在java.net.URLClassLoader.defineClass(URLClassLoader.java:454) />在java.n et.URLClassLoader.access $ 100(URLClassLoader.java:73)
在java.net.URLClassLoader $ 1.run(URLClassLoader.java:368)
在java.net.URLClassLoader $ 1.run(URLClassLoader.java :362)
at java.security.AccessController.doPrivileged(本机方法)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass (ClassLoader.java:424)
在sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:331)
在java.lang.ClassLoader.loadClass(ClassLoader.java:357)
>在sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)


是什么帮助了我(IntelliJ IDEA 2016.3):
文件->项目结构->工件- >添加JAR->选择主类->选择“复制到输出目录并通过清单链接”->确定->应用->构建->构建工件...->构建

#16 楼



尝试从jar中删除META-INF文件夹,添加清单并再次签名JAR,这对我有帮助:http://jehy.ru/articles/2013 / 12/13 /用于清单主要属性的无效签名文件摘要/

评论


+1的链接。从我正在使用的罐子中删除META-INF * .RSA和META-INF * .SF为我解决了问题。青年汽车

– KathyA。
2014年4月10日下午14:55

#17 楼

如果您在寻找不解包或篡改原始库但使用特殊JAR类加载器的Fat JAR解决方案,请在此处查看我的项目。

免责声明:我没有编写代码,只是打包并将其发布在Maven Central上,并在我的自述文件中描述如何使用。

我个人使用它来创建包含BouncyCastle依赖项的可运行uber JAR。也许对您也有用。

#18 楼

对于那些对接受的解决方案有疑问的人,还有另一种方法可以使用DontIncludeResourceTransformer从阴影罐中排除资源:

https://maven.apache.org/plugins/maven-shade-plugin/examples /resource-transformers.html#DontIncludeResourceTransformer

          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                <resource>BC1024KE.DSA</resource>
            </transformer>
          </transformers>


从Shade 3.0开始,此转换器接受资源列表。在此之前,您只需要使用多个变压器,每个变压器只有一个资源。

#19 楼

当我在Intellij上说“找到了非托管pom文件”时,单击底部的“添加为Maven项目”时,这在Intellij中发生了。同时out文件夹已经生成。因此它没有得到最近的更改。

删除文件夹并运行程序对我来说解决了这个问题。然后重新创建out文件夹。

也请参阅Little Fox的答案。我收到的错误与他的错误非常相似。

#20 楼

我有一个类似的问题。原因是我在Windows框中使用的JDK与默认JRE不同。

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

#21 楼

如果在尝试为Xamarin.Android绑定项目绑定JAR文件时遇到此问题,请执行以下操作:


JARTOXML:警告J2XA006:反映com.your时出现缺少类错误。 class:清单主要属性的无效签名文件摘要


只需使用Winzip打开JAR文件并删除meta-inf目录。重建-工作完成

评论


这是一种可怕的技术。绝对可怕。在本地进行更正,请勿更改传入的jar

–sinisterrook
16年6月6日在14:16