When working with Java applications, you may encounter the following error like I did:
java.lang.IllegalAccessError: class com.auth.jwt.Util$ (in unnamed module @0x15ca7889) cannot access class sun.security.x509.X500Name (in module java.base) because module java.base does not export sun.security.x509 to unnamed module @0x15ca7889
This issue arises because your code is attempting to use the internal sun.security.x509.X500Name
class. Starting with Java 9, the Java Platform Module System (JPMS) restricts access to internal APIs such as sun.security.*
, making them inaccessible unless explicitly allowed.
Why This Happens
The sun.*
classes, including sun.security.x509.X500Name
, are part of Java’s internal APIs. These classes were never intended for public use and are subject to change without notice. From Java 9 onward, the module system enforces stricter boundaries, preventing access to these internal APIs unless explicitly exported.
How to Fix the Issue
Replace sun.security.x509.X500Name
with javax.security.auth.x500.X500Principal
The Java standard library provides javax.security.auth.x500.X500Principal
as a public API to handle X.500 names. This is the recommended approach because it avoids reliance on internal classes.
import javax.security.auth.x500.X500Principal;
public class TestUtil {
public static void main(String[] args) {
X500Principal principal = new X500Principal("CN=example, L=SomeCity, C=SomeCountry");
System.out.println("X500Principal: " + principal.getName());
}
}
If for some reason if you can’t update to X500Principal.
Like me, because it was getting used in imported library, second solution is for you.
Use the --add-exports
JVM Argument
javaOptions in Test += "--add-exports=java.base/sun.security.x509=ALL-UNNAMED"
This workaround should only be used as a last resort because it relies on internal APIs that could be removed in future Java releases.