Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Oct 6, 2025

Fixes an issue where JNDI and other JDK services fail with IllegalAccessException when running in Maven plugins with Java 9+.

Problem

When using Maven plugins with Java 9+, code that uses JNDI (such as Netty's DNS resolver) fails with:

javax.naming.NoInitialContextException: Cannot instantiate class: com.sun.jndi.dns.DnsContextFactory 
[Root exception is java.lang.IllegalAccessException: class javax.naming.spi.NamingManager (in module java.naming) 
cannot access class com.sun.jndi.dns.DnsContextFactory (in module jdk.naming.dns) because module jdk.naming.dns 
does not export com.sun.jndi.dns to module java.naming]

This occurs when:

  • The thread context classloader is set to a ClassRealm instance (as Maven does for plugins)
  • JNDI tries to load factory classes from JDK modules
  • The Java 9+ module system's access checks fail

The same code works fine when run as a regular Java application.

Root Cause

Java 9+ introduced module-aware class loading through ClassLoader.findClass(String moduleName, String name). When moduleName is not null, it indicates the JVM is trying to find a class in a specific named module.

The existing implementation simply returned null when moduleName != null, which meant:

  • ClassRealm couldn't find classes from named JDK modules
  • The module context was lost, breaking module access rules
  • JNDI and other services couldn't properly instantiate JDK internal classes

Solution

Modified ClassRealm.findClass(String moduleName, String name) to properly delegate to the parent classloader (or system classloader as fallback) when a module name is specified. This ensures JDK module classes are loaded in the correct module context, allowing JNDI and other services to work properly.

Testing

  • Added testLoadJdkModuleClassThroughJNDI() test case that reproduces the exact scenario from the issue (Netty using JNDI in Maven plugins)
  • All existing tests continue to pass (93 tests, 1 skipped)
  • Verified the fix works with explicit JNDI factory class names as used by Netty

Impact

  • Minimal changes: Only 16 lines added to findClass method
  • No breaking changes: All existing functionality preserved
  • Enables JNDI and other JDK services to work correctly in Maven plugins on Java 9+

Fixes #XX

Original prompt

This section details on the original issue you should resolve

<issue_title>IllegalAccessException for com.sun.jndi.dns.DnsContextFactory</issue_title>
<issue_description>I'm not quite sure where to place this bug - here, with Maven, with Netty, or with the affected Maven plugin. So I'm going to start here...

I am using the apicurio-registry-maven-plugin in my Maven build with Java 21.

Under the hood, this uses Netty. Under Windows, Netty uses JNDI to get the system DNS servers, essentially doing this:

        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
        env.put("java.naming.provider.url", "dns://");

        DirContext ctx = new InitialDirContext(env);
        String dnsUrls = (String) ctx.getEnvironment().get("java.naming.provider.url");

When this code runs in a Maven plugin, this fails with

javax.naming.NoInitialContextException: Cannot instantiate class: com.sun.jndi.dns.DnsContextFactory [Root exception is java.lang.IllegalAccessException: class javax.naming.spi.NamingManager (in module java.naming) cannot access class com.sun.jndi.dns.DnsContextFactory (in module jdk.naming.dns) because module jdk.naming.dns does not export com.sun.jndi.dns to module java.naming]

When I run the same code directly as a Java application, with the same JVM options, classpath etc., it works fine. I suspect that this has something to do with the plexus-classworlds classloader system, but I'm at a loss what, why and how.

System:
Windows 11
OpenJDK 21.0.5 (Eclipse Temurin-21.0.5+11)
Maven 3.9.9
apicurio-registry-maven-plugin 3.0.4
Netty 4.1.111
</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #119

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Fixes module-aware class loading in findClass(String moduleName, String name) to properly delegate to parent/system classloader for JDK module classes. This resolves IllegalAccessException when loading classes like com.sun.jndi.dns.DnsContextFactory through JNDI in Maven plugins.

When moduleName != null, the method now delegates to the parent classloader (or system classloader as fallback) instead of returning null, ensuring proper module context is preserved for JDK internal classes.

Co-authored-by: slachiewicz <[email protected]>
@Copilot Copilot AI changed the title [WIP] Fix IllegalAccessException for DnsContextFactory Fix IllegalAccessException for JDK module classes in ClassRealm Oct 6, 2025
@Copilot Copilot AI requested a review from slachiewicz October 6, 2025 22:03
Copilot finished work on behalf of slachiewicz October 6, 2025 22:03
@slachiewicz slachiewicz marked this pull request as ready for review October 6, 2025 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IllegalAccessException for com.sun.jndi.dns.DnsContextFactory
2 participants