我的java程序被打包在一个jar文件中,并使用了一个外部jar库,bouncy castle。我的代码编译良好,但运行jar会导致以下错误:
java.lang.SecurityException: Manifest主属性的签名文件摘要无效
我在谷歌上搜索了一个多小时,想要找到一个解释,但几乎没有什么价值。如果有人看到这个错误之前,可以提供一些帮助,我将不胜感激。
我的java程序被打包在一个jar文件中,并使用了一个外部jar库,bouncy castle。我的代码编译良好,但运行jar会导致以下错误:
java.lang.SecurityException: Manifest主属性的签名文件摘要无效
我在谷歌上搜索了一个多小时,想要找到一个解释,但几乎没有什么价值。如果有人看到这个错误之前,可以提供一些帮助,我将不胜感激。
当前回答
请使用以下命令
zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*.DSA'
其他回答
比较新jar和旧jar中的META-INF文件夹(在添加新库之前)。有可能会有新的文件。如果是,可以删除。这应该会有所帮助。 问候, 999米甲
您可以使用Shadow生成一个jar。
Shadow是一个Gradle插件,用于将项目的依赖类和资源组合到一个输出Jar中。组合罐通常被称为fat-jar或super - Jar。
Modify build.gradle plugins { ... // ① Add the shadow plugin id "com.github.johnrengelman.shadow" version "5.2.0" } ... // ② Config the shadow jar, its name is baseName-1.0-classifier.jar shadowJar { archiveBaseName.set('baseName') archiveClassifier.set('classifier') archiveVersion.set('1.0') manifest { attributes 'Main-Class': 'Main' } } // ③ Disable the default jar task jar.enabled = false // ④ Execute the shadowJar task when compiling build.dependsOn(shadowJar) Execute the command gradle build, the jar file will be generated: <Project Directory>/build/libs/baseName-1.0-classifier.jar
对于那些使用gradle并试图创建和使用fat jar的人来说,下面的语法可能会有所帮助。
jar {
doFirst {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
如果您在尝试为Xamarin绑定JAR文件时遇到这种情况。Android绑定项目如下:
J2XA006:在反映清单主属性的com.your.class:无效签名文件摘要时引发了缺少类错误
只需使用Winzip打开JAR文件并删除meta-inf目录。重建-工作完成
一种策略包括使用ANT来简化从每个Jar文件中删除签名。它将采取下列步骤:
复制舱单。MF在临时文件中 从临时文件中删除Name和SHA条目 用临时清单创建一个临时Jar文件 移除临时舱单 将原始Jar文件与临时Jar文件交换
下面是一个ANT宏def做的工作:
<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>