英文:
cannot access class jdk.xml.internal.JdkXmlUtils
问题
我正在更新一个旧的针对 hybris/SAP-Commerce(2005年版本)的公司内部扩展。这是一个用于调用 API 的扩展。
我不知道这个扩展有多旧。
然而,在将其应用于 Java 11 时,我遇到了诸如这样的问题(链接:https://stackoverflow.com/questions/57318521/java-11-import-javax-xml-ws-webfault-cannot-resolve-symbol-ws)。
在重新运行命令 ./hybrisserver.sh 后,一个特定的(只读的)'.jar' 文件抛出以下异常:
无法实例化[<给定 .jar 中的类>]:
构造函数引发了异常;
嵌套异常是 java.lang.IllegalAccessError:
类 com.sun.org.apache.xml.internal.resolver.Catalog(在未命名模块中 @0x9a92113)无法访问类 jdk.xml.internal.JdkXmlUtils(在模块 java.xml 中),
因为模块 java.xml 没有将 jdk.xml.internal 导出到未命名模块 @0x9a92113
我以为可能是 JDK 的问题,所以我尝试了不同的发行版。
(我正在使用 Manjaro Linux KDE 20.1,并且使用 sdkman)
以下是我测试过的发行版:
供应商 | 版本 | 发行版 | 标识符
--------------------------------------------------------
AdoptOpenJDK | 11.0.8.j9 | adpt | 11.0.8.j9-adpt
Java.net | 11.0.8 | open | 11.0.8-open
SAP | 11.0.8 | sapmchn | 11.0.8-sapmchn
每个版本都抛出了相同的错误。
英文:
I'm updating an old Company-intern extension for hybris/SAP-Commerce (2005). it's an extension to consume an API.
I don't know how old the extension is.
However, while applying it to java 11, I spot problems like this (https://stackoverflow.com/questions/57318521/java-11-import-javax-xml-ws-webfault-cannot-resolve-symbol-ws).
After rerun the command ./hybrisserver.sh, a given (read only) '.jar' file throws follow exception:
Failed to instantiate [<class from given .jar>]:
Constructor threw exception;
nested exception is java.lang.IllegalAccessError:
class com.sun.org.apache.xml.internal.resolver.Catalog (in unnamed module @0x9a92113) cannot access class jdk.xml.internal.JdkXmlUtils (in module java.xml) because module java.xml does not export jdk.xml.internal to unnamed module @0x9a92113
I thought it could be a jdk problem, so I tried different distributions.
(I'm working on Manjaro Linux KDE 20.1 with sdkman)
Follow distributions I've tested:
Vendor | Version | Dist | Identifier
--------------------------------------------------------
AdoptOpenJDK | 11.0.8.j9 | adpt | 11.0.8.j9-adpt
Java.net | 11.0.8 | open | 11.0.8-open
SAP | 11.0.8 | sapmchn | 11.0.8-sapmchn
Each of it throw the same error
答案1
得分: 8
这不是JDK的错误,也不是你的JVM安装出现了问题。实际上,这是你尝试构建的旧代码中存在的问题。代码正在使用JVM内部包中的一个类。它不应该这样做。它不应该需要这样做。
直接使用内部包中的类一直都是一个不好的想法,因为它们可能在没有任何通知的情况下发生更改。自我记忆以来,旧的Java文档中一直包含有关此的警告。
从Java 9开始,默认情况下,模块系统将阻止应用程序代码访问内部API。这就是你在这里遇到的问题。
有两种方法可以解决这个问题:
-
更好的方法是修改你尝试编译的代码,使其不再依赖于那个类。(如果不看到你的代码,我们无法提供关于如何做到这一点的建议……)
-
另一种方法是在
java
命令行中使用--add-opens
选项,以打破模块封装以允许访问这个类。对于不使用模块的代码,以下内容应该可以实现:--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
警告:这种方法应该被视为一个短期解决方案。你正在使用的内部API在下一个Java版本中可能会被更改或移除。
注意:截至JDK 10,com.sun.org.apache.xml.internal.resolver.Catalog
类在OpenJDK源代码中已不再存在。它已被javax.xml.catalog.Catalog
取代。我猜你从依赖项中获取了“内部”版本,而不是JDK版本。
英文:
This is not a JDK bug, or fault in your JVM installation(s). It is actually a problem with the old code you are trying to build. The code is using a class in a JVM internal package. It shouldn't do that. It shouldn't need to do that.
It has always been a bad idea to directly use classes in internal packages since they are subject to change without any notice. The old Java documentation has included warnings about this ... for as long as I can remember.
As of Java 9, the module system will (by default) prevent application code from accessing internal APIs. And that is what you are running into here.
There are two ways to solve this:
-
The better way is to modify the code you are trying to compile so that it no longer depends on that class. (We can't offer suggestions as to how to do this without seeing your code ...)
-
The other way is to use
--add-opens
options in thejava
command line to break module encapsulation to allow access the class. The following should do it for code that doesn't use modules.--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
WARNING: this approach should be viewed as a short term work-around. The internal API you are using could be changed or removed with the next Java release.
NOTE : as of JDK 10, the com.sun.org.apache.xml.internal.resolver.Catalog
class no longer exists in the OpenJDK source code. It has been replaced by javax.xml.catalog.Catalog
. My guess is that you are getting the "internal" version from a dependency rather than the JDK.
答案2
得分: 3
如果您正在使用Maven构建项目,您应该添加JVM参数:
--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
例如:
英文:
if you are using maven to build your project you should add the JVM argument :
--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
for example :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED</argLine>
</configuration>
</plugin>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论