gpt4 book ai didi

java - 自 JRE 8u232 起,JNI 无法在签名的 JAR 中找到类

转载 作者:行者123 更新时间:2023-12-03 02:11:18 27 4
gpt4 key购买 nike

我有一个带有签名 JAR 的 Java 应用程序,其中包含所有类文件和资源。该应用程序附带了捆绑的 JRE 和可执行文件。该可执行文件是用 C++ 编写的,并使用 JNI 加载 VM 并启动应用程序。这在过去是完美的。

从 JRE 8u232(例如 Azul,还有 Oracle 的 8u231)开始,应用程序不再运行,因为无法使用 JNI 的 FindClass() 函数找到指定的主类。它返回一个空指针,当我调用 ExceptionDescribe() 函数时,它会显示 Java 方法 JarVerifier::processEntry 中发生的 NPE:

Exception in thread "main" java.lang.NullPointerException
at java.util.jar.JarVerifier.processEntry(JarVerifier.java:303)
at java.util.jar.JarVerifier.update(JarVerifier.java:230)
at java.util.jar.JarFile.initializeVerifier(JarFile.java:383)
at java.util.jar.JarFile.ensureInitialization(JarFile.java:612)
at java.util.jar.JavaUtilJarAccessImpl.ensureInitialization(JavaUtilJarAccessImpl.java:69)
at sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:991)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:451)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)

当我从 JAR 的 META-INF 文件夹中删除 *.RSA 和 *.SF 文件时,它会再次工作。当我从 JRE 的“bin”文件夹中调用“java”可执行文件时,它也可以工作,如下所示:

java -cp "path/to/my/jar" org.company.name.MyMainclass

在我看来,导致此问题的 Java 8(或更高版本)发生了一些变化。但是我找不到原因。这里可能出现什么问题?

更新:

我使用 JarVerifier 类进行了一些远程调试,并观察到以下情况:

  • JarVerifier::process 使用 get() 多次访问 hashmap sigFileData(第 303 行)
  • 在某个时刻调用 JarVerifier::doneWithMeta ,在再次调用 get() 方法之前将映射设置为 null
  • 这仅在通过 JNI 启动应用程序时发生

更新2:

我找到了导致问题的原因并让我的应用程序再次运行,但我不明白为什么。启动应用程序的可执行文件读取带有多个参数的文本文件以传递给VM(例如系统属性、主类名称等)。一个参数将系统属性 java.util.logging.config.file 设置为同一目录中的 logging.properties 文件。该属性文件的开头如下:

handlers = org.mycompany.juli2log4j.JuliToLog4jHandler
.handlers = org.mycompany.juli2log4j.JuliToLog4jHandler

这些语句和处理程序类是 10 年前编写的。当我删除“.handlers”语句时,我的应用程序可以正常工作,并且日志记录似乎仍然可以正常工作。

最让我困惑的是这一行如何在应用程序启动时导致 JarVerifier 类中出现 NullPointerException。怎么可能?有什么联系?

最佳答案

LogManager文档表明 .handlers 无效,因为它缺少记录器说明符:

A property "<logger>.handlers". This defines a whitespace or comma separated list of class names for handlers classes to load and register as handlers to the specified logger. Each class name must be for a Handler class which has a default constructor. Note that these Handlers may be created lazily, when they are first used.

我的猜测是 8u232 引入了一项更改,不再处理(或推断)丢失的记录器名称。可能存在到以前不存在的 null 的映射和/或对 null 键控记录器的新引用。

关于java - 自 JRE 8u232 起,JNI 无法在签名的 JAR 中找到类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59778258/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com