无法访问类jdk.xml.internal.JdkXmlUtils

6

我正在更新一个旧的公司内部扩展程序,用于hybris/SAP-Commerce(2005年)。它是一个用于调用API的扩展程序。

我不知道这个扩展程序有多老。

然而,当我将其应用于Java 11时,我遇到了一些问题,比如 (Java 11: import javax.xml.ws.WebFault: "Cannot resolve symbol ws")。

在重新运行命令 ./hybrisserver.sh 后,一个给定(只读)的 '.jar' 文件抛出以下异常:

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

我认为这可能是jdk的问题,所以我尝试了不同版本。

以下是我测试过的版本:

  • Manjaro Linux KDE 20.1 with sdkman
 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 

它们每一个都抛出相同的错误


1
知道JAR文件的名称会很有用,这是您自己的还是由其他人维护的?他们是否有问题跟踪器来提交错误?您可以做的一件事是将维护者指向java.xml.catalog API(自Java 9以来新推出的API),该API提供了一个标准/支持的API来解析外部资源。 - Alan Bateman
如果您能够,请分享一个能够产生该错误信息的复现程序。 - Johannes Kuhn
2个回答

9
这不是JDK的错误,也不是您JVM安装的故障。实际上,这是您尝试构建的旧代码存在问题。该代码正在使用JVM内部包中的一个类。它不应该这样做。它不应该需要这样做。
直接使用内部包中的类一直都是个坏主意,因为它们可能会在没有任何通知的情况下发生变化。自我记忆以来,旧的Java文档已经包括了这方面的警告。
从Java 9开始,默认情况下,模块系统将防止应用程序代码访问内部API。这就是您在此处遇到的问题。
有两种解决方法:
  • 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 the java 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.


注意:从JDK 10开始,com.sun.org.apache.xml.internal.resolver.Catalog类不再存在于OpenJDK源代码中。它已被javax.xml.catalog.Catalog所取代。我猜测您是从依赖项中获取了“内部”版本,而不是JDK自带的版本。


4
如果您正在使用Maven构建项目,您应该添加JVM参数:
--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED

例如:
           <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>

2
但请注意,这应该被视为一种临时解决方法。它可能会停止工作。正确的修复方法是更改您的代码,以替换此使用内部类的方式,使用更合适的内容;请参见我的答案。(Alan Bateman的评论可能在这种特殊情况下提供线索。) - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接