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

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

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


当前回答

Error: A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes at sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:314) at sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:268) at 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) at java.util.jar.JarFile.getInputStream(JarFile.java:450) at sun.misc.URLClassPath$JarLoader$2.getInputStream(URLClassPath.java:977) at sun.misc.Resource.cachedInputStream(Resource.java:77) at sun.misc.Resource.getByteBuffer(Resource.java:160) at java.net.URLClassLoader.defineClass(URLClassLoader.java:454) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

帮助我的(IntelliJ IDEA 2016.3): 文件->项目结构-> Artifacts ->添加JAR ->选择主类->选择“通过manifest复制到输出目录和链接”->确定->应用->构建->构建Artifacts…- >构建

其他回答

如果你正在使用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
}

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

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开始,这个转换器接受一个资源列表。在此之前,您只需要使用多个转换器,每个转换器具有一个资源。

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

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

比较新jar和旧jar中的META-INF文件夹(在添加新库之前)。有可能会有新的文件。如果是,可以删除。这应该会有所帮助。 问候, 999米甲

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