Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,23 @@ private Class<?> unsynchronizedLoadClass(String name, boolean resolve) throws Cl
@SuppressWarnings("Since15")
protected Class<?> findClass(String moduleName, String name) {
if (moduleName != null) {
return null;
// Delegate to parent for module-aware class loading to maintain proper module context
// This is crucial for JDK internal classes like com.sun.jndi.dns.DnsContextFactory
ClassLoader parent = getParent();
if (parent != null) {
try {
// Use the parent's module-aware findClass method
return parent.loadClass(name);
} catch (ClassNotFoundException e) {
return null;
}
}
// If no parent, delegate to system classloader for JDK module classes
try {
return ClassLoader.getSystemClassLoader().loadClass(name);
} catch (ClassNotFoundException e) {
return null;
}
}
try {
return findClassInternal(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@
* limitations under the License.
*/

import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.Hashtable;
import java.util.concurrent.CountDownLatch;

import org.codehaus.classworlds.ClassRealmAdapter;
Expand Down Expand Up @@ -265,6 +270,39 @@ void testParallelDeadlockClassRealm() throws InterruptedException {
}
}

/**
* Test that JDK internal classes from named modules (like com.sun.jndi.dns.DnsContextFactory)
* can be properly accessed when loaded through ClassRealm. This is crucial for JNDI to work
* correctly in Maven plugins.
*
* @see <a href="https://github.com/codehaus-plexus/plexus-classworlds/issues/XX">Issue XX</a>
*/
@Test
void testLoadJdkModuleClassThroughJNDI() throws Exception {
// Use system classloader as base to ensure JDK module classes can be loaded
ClassRealm realm = new ClassRealm(new ClassWorld(), "test", ClassLoader.getSystemClassLoader());

// Set the thread's context classloader to the realm
Thread currentThread = Thread.currentThread();
ClassLoader originalClassLoader = currentThread.getContextClassLoader();
try {
currentThread.setContextClassLoader(realm);

// Try to instantiate DnsContextFactory via JNDI with explicit factory class name
// This is how Netty uses JNDI under Windows
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
env.put(Context.PROVIDER_URL, "dns:");

// This should succeed without IllegalAccessException
DirContext ctx = new InitialDirContext(env);
assertNotNull(ctx);
ctx.close();
} finally {
currentThread.setContextClassLoader(originalClassLoader);
}
}

private void doOneDeadlockAttempt() throws InterruptedException {
// Deadlock sample graciously ripped from http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html
final ClassRealm cl1 = new ClassRealm(new ClassWorld(), "cl1", null);
Expand Down