java - 在子目录中创建 jar 文件时出现 NoClassDefFoundError

标签 java jar bouncycastle classnotfoundexception

当我在子目录中创建 jar 文件时,bcprov-jdk15on-159.jar 中的 BouncyCaSTLeProvider 类加载失败,并出现 ClassNotFoundException。我认为创建 jar 文件的位置不应该对其内容和行为产生影响。

这是创建工作 jar 的示例。

$ jar cfm MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar
$ java -jar MyProject.jar
hello provider: BC version 1.59

下面是一个示例,其中使用完全相同的输入文件运行 jar,但 jar 文件目标不同,导致 jar 失败。

$ jar cfm dist/MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar
$ java -jar dist/MyProject.jar
Error: Unable to initialize main class Main
Caused by: java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider

这是文件Manifest.txt

Manifest-Version: 1.0
Main-Class: Main
Class-Path: bcprov-jdk15on-159.jar

这是使用 BouncyCaSTLeProvider 类的 Main.java 文件。

public class Main {
    public static void main(String... arg) {
        java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        java.security.Provider p = java.security.Security.getProvider("BC");
        System.out.println("hello provider: " + p);
    }
}

我在 JDK 8 和 JDK 9 以及 JDK jar 命令(如上所示)和 Ant 的 jar 任务中都看到了这种行为。

我在尝试升级PCSecrets时偶然发现了这个问题。在 Java 9 下工作的密码管理器。

最佳答案

上述失败的原因是Java不会从jar文件中加载bcprov-jdk15on-159.jar,而是从类路径中加载,类路径似乎根据调用的位置而有所不同 jar 。当生成的 jar 文件与 bcprov-jdk15on-159.jar 位于同一目录中时,它会从该目录加载它,并且命令调用工作正常。当生成的jar文件位于其他目录时,无法加载bcprov-jdk15on-159.jar并抛出ClassNotFoundExceptionthis 中提供了将 jar 包含在 jar 中的解决方案。问题。有趣的是,this answer ,被投票了 26 次,也是基于同样的错误假设。

我通过比较生成的 jar 文件的二进制图像找到了答案。它们似乎仅在 META-INF/MANIFEST.MF 文件的时间戳上有所不同。通过使用命令并行生成两个文件 jar cfm dist/MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar & jar cfm MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159 .jar 我有两个完全相同的 jar 文件,但仍然存在问题。这促使我查看这两个文件的执行环境,而不是文件本身。

关于java - 在子目录中创建 jar 文件时出现 NoClassDefFoundError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49466170/

相关文章:

java - 静态方法参数的同步

java - 在 NDK 中获取 Android ID 时出错

java - Maven 程序集 jar 中的 Datanucleus JDO

c# - Bouncy CaSTLe 中的 TlsSignerCredentials 和 TlsAgreementCredentials 有什么区别

java - 无效的 keystore 格式 - tomcat

java - 进入 UI 线程

java - 使用maven创建带有xml文件的jar文件

java - 在eclipse中调试jar文件

c# - Java BouncyCaSTLe AES 解密的 C# 等价物是什么?

java - 无法理解 Java 算法中的执行顺序(k= 和++k)