“签名文件无效” 当尝试运行 .jar 时

发布于 2024-07-24 20:26:05 字数 291 浏览 3 评论 0原文

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

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

我已经用谷歌搜索了一个多小时寻找解释并发现几乎没有什么价值。 如果有人以前见过这个错误并可以提供一些帮助,我将不胜感激。

My java program is packaged in a jar file and makes use of an external jar library, bouncy castle. My code compiles fine, but running the jar leads to the following error:

Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

I've googled for over an hour searching for an explanation and found very little of value. If anyone has seen this error before and could offer some help, I would be obliged.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(24

层林尽染 2024-07-31 20:26:07

两个不同的签名者可能会扰乱 java 的思维。

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

It's possible that two different signers mess up java mind.

Try removing META-INF folder from jar, adding manifest and signing JAR again, it helped me: http://jehy.ru/articles/2013/12/13/invalid-signature-file-digest-for-manifest-main-attributes/

寂寞清仓 2024-07-31 20:26:07

如果您正在寻找无需解压或篡改原始库但具有特殊 JAR 类加载器的 Fat JAR 解决方案,请查看 我的项目在这里

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

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

If you are looking for a Fat JAR solution without unpacking or tampering with the original libraries but with a special JAR classloader, take a look at my project here.

Disclaimer: I did not write the code, just package it and publish it on Maven Central and describe in my read-me how to use it.

I personally use it for creating runnable uber JARs containing BouncyCastle dependencies. Maybe it is useful for you, too.

红ご颜醉 2024-07-31 20:26:07

您可以使用 Shadow 生成 jar。

Shadow 是一个 Gradle 插件,用于将项目的依赖类和资源组合到单个输出 Jar 中。 组合后的 Jar 通常称为 fat-jar 或 uber-jar。

  1. 修改build.gradle

    插件 { 
          ... 
          // ① 添加shadow插件 
          id“com.github.johnrengelman.shadow”版本“5.2.0” 
      } 
    
      ... 
      // ② 配置shadow jar,名称为baseName-1.0-classifier.jar 
      影子罐{ 
          archiveBaseName.set('baseName') 
          archiveClassifier.set('分类器') 
          archiveVersion.set('1.0') 
          显现 { 
              属性 '主类': '主' 
          } 
      } 
    
      // ③ 禁用默认jar任务 
      jar.启用 = false 
      // ④ 编译时执行shadowJar任务 
      build.dependsOn(shadowJar) 
      
  2. 执行命令gradle build,会生成jar文件:

    • <项目目录>/build/libs/baseName-1.0-classifier.jar

You can use Shadow to generate a jar.

Shadow is a Gradle plugin for combining a project's dependency classes and resources into a single output Jar. The combined Jar is often referred to a fat-jar or uber-jar.

  1. 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)
    
  2. Execute the command gradle build, the jar file will be generated:

    • <Project Directory>/build/libs/baseName-1.0-classifier.jar
镜花水月 2024-07-31 20:26:07

对于那些对接受的解决方案有困难的人,还有另一种方法可以使用 DontIncludeResourceTransformer 从着色 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 开始,此变压器接受资源列表。 在此之前,您只需使用多个变压器,每个变压器具有一个资源。

For those who have trouble with the accepted solution, there is another way to exclude resource from shaded jar with 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>

From Shade 3.0, this transformer accepts a list of resources. Before that you just need to use multiple transformer each with one resource.

甜味超标? 2024-07-31 20:26:07

当我单击底行的“添加为 Maven 项目”时,当 Intellij 说“找到非托管 pom 文件”时,我在 Intellij 中发生了这种情况。 此时out文件夹已经生成了。 所以它没有得到最近的改变。

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

也可以看看小狐狸的回答。 我收到的错误与他的非常相似。

This happened to me in Intellij when I clicked "Add as a Maven Project" on bottom line when Intellij said "non-managed pom files found.". Meanwhile out folder was already generated. So it did not get recent changes.

Deleting out folder and running the program solved the issue for me. out folder was then recreated.

See the answer of Little Fox as well. The error I received was very similar to his.

残月升风 2024-07-31 20:26:07

对于使用 kotlin script(kts) 作为构建脚本的人:

task("fatJar", type = Jar::class) {
baseName = "${project.name}-fat"
manifest {
    attributes["Implementation-Title"] = "Watcher Jar File"
    attributes["Implementation-Version"] = version
    attributes["Main-Class"] = "MainKt"
}
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) {
    exclude(listOf("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA"))
}
with(tasks.jar.get() as CopySpec)

}

For someone who using kotlin script(kts) as building script:

task("fatJar", type = Jar::class) {
baseName = "${project.name}-fat"
manifest {
    attributes["Implementation-Title"] = "Watcher Jar File"
    attributes["Implementation-Version"] = version
    attributes["Main-Class"] = "MainKt"
}
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) {
    exclude(listOf("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA"))
}
with(tasks.jar.get() as CopySpec)

}

海螺姑娘 2024-07-31 20:26:07

正如 @MattW 提到的,在 JCE 提供程序(如 BouncyCastle)上执行此操作可能会导致发生新的异常。

无论如何,如果您想修复 OP 中提到的错误,并且使用 Gradle Kotlin 构建脚本,则可以使用以下代码使其工作:

tasks.withType<Jar> {
    excludes += listOf("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
}

这将从类型为“Jar”的任务中排除文件列表,无论是什么这些是任务。

As @MattW mentioned, doing this on a JCE provider (like BouncyCastle) can cause new exceptions to occur.

Regardless, if you want to fix the error mentioned in the OP, and you use Gradle Kotlin Build Script, you can use following code to make it work:

tasks.withType<Jar> {
    excludes += listOf("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
}

This will exclude a list of files from tasks with type "Jar", regardless of what tasks these are.

旧人 2024-07-31 20:26:07

我有类似的问题。 原因是我使用 JDK 进行编译,其 JRE 与我的 Windows 机器中的默认 JRE 不同。

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

I had a similar problem. The reason was that I was compiling using a JDK with a different JRE than the default one in my Windows box.

Using the correct java.exe solved my problem.

世界和平 2024-07-31 20:26:07

如果您在尝试为 Xamarin.Android 绑定项目绑定 JAR 文件时遇到此问题,如下所示:

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

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

If you're getting this when trying to bind JAR files for a Xamarin.Android bindings project like so:

JARTOXML : warning J2XA006: missing class error was raised while reflecting com.your.class : Invalid signature file digest for Manifest main attributes

Just open the JAR files using Winzip and delete the meta-inf directories. Rebuild - job done

碍人泪离人颜 2024-07-31 20:26:06

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

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

For those who got this error when trying to create a shaded uber-jar with maven-shade-plugin, the solution is to exclude manifest signature files by adding the following lines to the plugin configuration:

<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>
撑一把青伞 2024-07-31 20:26:06

对于那些使用 gradle 并尝试创建和使用 fat jar 的人来说,以下语法可能会有所帮助。

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

For those using gradle and trying to create and use a fat jar, the following syntax might help.

jar {
    doFirst {
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
}
你穿错了嫁妆 2024-07-31 20:26:06

请使用以下命令

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

Please use the following command

zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*.DSA'
橘香 2024-07-31 20:26:06

您的某些依赖项可能是签名的 jar 文件。 当您将它们全部组合成一个大 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 元素应该阻止 有关修改日期为未来的文件的错误

我在链接线程中发现的其他变体对我不起作用。

Some of your dependencies are likely signed jarfiles. When you combine them all into one big jarfile, the corresponding signature files are still present, and no longer match the "big combined" jarfile, so the runtime halts thinking the jar file has been tampered with (which it...has so to speak).

Assuming you're using ant, you can solve the problem by eliminating the signature files from your jarfile dependencies. Unfortunately, it's not possible to do this in one step in ant.

However, I was able to get this working with Ant in two steps, without specifically naming each jarfile dependency, by using:

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

The sleep element is supposed to prevent errors about files with modification dates in the future.

Other variations I found in the linked threads didn't work for me.

遗失的美好 2024-07-31 20:26:06

此处列出的解决方案可能会提供指导。

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


底部线 :

最好将官方 jar 保留为
是,只需将其添加为清单文件中的依赖项即可
应用程序 jar 文件。

The solution listed here might provide a pointer.

Invalid signature file digest for Manifest main attributes

Bottom line :

It's probably best to keep the official jar as
is and just add it as a dependency in the manifest file for your
application jar file.

莫多说 2024-07-31 20:26:06

安全性已经是一个棘手的话题,但我很失望地看到最流行的解决方案是删除安全签名。 JCE 需要这些签名 。 Maven 阴影分解了 BouncyCastle jar 文件,该文件将签名放入 META-INF 中,但 BouncyCastle 签名对于新的 uber-jar 无效(仅适用于 BC jar),这就是导致无效签名错误的原因在此线程中。

是的,按照@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 中。

更新

另一种方法(正确的方法?)是使用 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 证书。

Security is already a tough topic, but I'm disappointed to see the most popular solution is to delete the security signatures. JCE requires these signatures. Maven shade explodes the BouncyCastle jar file which puts the signatures into META-INF, but the BouncyCastle signatures aren't valid for a new, uber-jar (only for the BC jar), and that's what causes the Invalid signature error in this thread.

Yes, excluding or deleting the signatures as suggested by @ruhsuzbaykus does indeed make the original error go away, but it can also lead to new, cryptic errors:

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

By explicitly specifying where to find the algorithm like this:

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

I was able to get a different error:

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

JCE can't authenticate the provider because we've deleted the cryptographic signatures by following the suggestion elsewhere in this same thread.

The solution I found was the executable packer plugin that uses a jar-in-jar approach to preserve the BouncyCastle signature in a single, executable jar.

UPDATE:

Another way to do this (the correct way?) is to use Maven Jar signer. This allows you to keep using Maven shade without getting security errors. HOWEVER, you must have a code signing certificate (Oracle suggests searching for "Java Code Signing Certificate"). The POM config looks like this:

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

No, there's no way to get JCE to recognize a self-signed cert, so if you need to preserve the BouncyCastle certs, you have to either use the jar-in-jar plugin or get a JCE cert.

装迷糊 2024-07-31 20:26:06

我在使用 IntelliJ IDEA 14.01 时遇到了这个问题。

我能够通过以下方式修复它:

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

库中选择主类

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

I had this problem when using IntelliJ IDEA 14.01.

I was able to fix it by:

File->Project Structure->Add New (Artifacts)->jar->From Modules With Dependencies on the Create Jar From Module Window:

Select you main class

JAR File from Libraries
Select copy to the output directory and link via manifest

╰つ倒转 2024-07-31 20:26:06

我遇到了同样的问题,在某处参考后,它的工作原理如下:

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

I faced the same issue, after reference somewhere, it worked as below changing:

<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>
伴我老 2024-07-31 20:26:06

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

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

Assuming you build your jar file with ant, you can just instruct ant to leave out the META-INF dir. This is a simplified version of my ant target:

<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>
壹場煙雨 2024-07-31 20:26:06

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

最后,这个 帮我

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

猜猜我的 jar 文件中删除了什么?!

deleting: META-INF/ECLIPSE_.SF 
deleting: META-INF/ECLIPSE_.RSA

看来这个问题与一些 eclipse 相关的文件有关。

I've recently started using IntelliJ on my projects. However, some of my colleagues still use Eclipse on the same projects. Today, I've got the very same error after executing the jar-file created by my IntelliJ. While all the solutions in here talking about almost the same thing, none of them worked for me easily (possibly because I don't use ANT, maven build gave me other errors which referred me to http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException, and also I couldn't figure out what are the signed jars by myself!)

Finally, this helped me

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

Guess what's been removed from my jar file?!

deleting: META-INF/ECLIPSE_.SF 
deleting: META-INF/ECLIPSE_.RSA

It seems that the issue was relevant to some eclipse-relevant files.

挥剑断情 2024-07-31 20:26:06

创建 fat 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'
    }
}

I had the same issue in gradle when creating a fat Jar; updating the build.gradle file with an exclude line corrected the problem.

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'
    }
}
久伴你 2024-07-31 20:26:06

如果您使用 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
}

In case you're using gradle, here is a full farJar task:

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
}
冰之心 2024-07-31 20:26:06

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

Compare the folder META-INF in new jar with old jar (before you added new libraries). It is possibility that there will be new files. If yes, you can remove them. It should helps.
Regards,
999michal

单身狗的梦 2024-07-31 20:26:06

策略包括使用 ANT 来简化从每个 Jar 文件中删除签名的过程。 它将继续执行以下步骤:

  1. 将 MANIFEST.MF 复制到临时文件中
  2. 从临时文件中删除 NameSHA 条目 使用
  3. 临时清单创建临时 Jar 文件
  4. 删除临时清单
  5. 将原始 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>

A strategy would consist in using ANT to simplify the removal of the signature from each Jar file. It would proceed with the following steps:

  1. Copying the MANIFEST.MF in a temporary file
  2. Removing the Name and SHA entries from the temporary file
  3. Creating a temporary Jar file with the temporary manifest
  4. Removing the temporary manifest
  5. Swapping the original Jar file with the temporary one

Here is an ANT macrodef doing the work:

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

`

The definition can then be called this way in an ANT task:

<target name="unsignJar">
    <unsignjar jarFile="org.test.myjartounsign.jar" />
</target>
终难遇 2024-07-31 20:26:06

错误:发生 JNI 错误,请检查您的安装并重试
线程“main”中出现异常 java.lang.SecurityException:Manifest 主要属性的签名文件摘要无效
在 sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:314)
在 sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:268)
在 java.util.jar.JarVerifier.processEntry(JarVerifier.java:316)
在 java.util.jar.JarVerifier.update(JarVerifier.java:228)
在 java.util.jar.JarFile.initializeVerifier(JarFile.java:383)
在 java.util.jar.JarFile.getInputStream(JarFile.java:450)
在 sun.misc.URLClassPath$JarLoader$2.getInputStream(URLClassPath.java:977)
在 sun.misc.Resource.cachedInputStream(Resource.java:77)
在 sun.misc.Resource.getByteBuffer(Resource.java:160)
在 java.net.URLClassLoader.defineClass(URLClassLoader.java:454)
在 java.net.URLClassLoader.access$100(URLClassLoader.java:73)
在 java.net.URLClassLoader$1.run(URLClassLoader.java:368)
在 java.net.URLClassLoader$1.run(URLClassLoader.java:362)
在 java.security.AccessController.doPrivileged(本机方法)
在 java.net.URLClassLoader.findClass(URLClassLoader.java:361)
在 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 -> 选择主类-> 选择“复制到输出目录并通过清单链接”-> 好的-> 申请-> 构建-> 构建工件... -> 建造

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)

What helped me (IntelliJ IDEA 2016.3):
File -> Project Structure -> Artifacts -> Add JAR -> Select Main Class -> Choose "copy to the output directory and link via manifest" -> OK -> Apply -> Build -> Build Artifacts... -> Build

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文