cannot access class jdk.xml.internal.JdkXmlUtils

23.5k Views Asked by At

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

2

There are 2 best solutions below

0
On

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


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.

1
On

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>