Skip to content

Commit 26f4f49

Browse files
Copilotslachiewicz
andcommitted
Fix IllegalAccessException for JDK module classes in ClassRealm
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]>
1 parent 9d05605 commit 26f4f49

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

src/main/java/org/codehaus/plexus/classworlds/realm/ClassRealm.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,23 @@ private Class<?> unsynchronizedLoadClass(String name, boolean resolve) throws Cl
218218
@SuppressWarnings("Since15")
219219
protected Class<?> findClass(String moduleName, String name) {
220220
if (moduleName != null) {
221-
return null;
221+
// Delegate to parent for module-aware class loading to maintain proper module context
222+
// This is crucial for JDK internal classes like com.sun.jndi.dns.DnsContextFactory
223+
ClassLoader parent = getParent();
224+
if (parent != null) {
225+
try {
226+
// Use the parent's module-aware findClass method
227+
return parent.loadClass(name);
228+
} catch (ClassNotFoundException e) {
229+
return null;
230+
}
231+
}
232+
// If no parent, delegate to system classloader for JDK module classes
233+
try {
234+
return ClassLoader.getSystemClassLoader().loadClass(name);
235+
} catch (ClassNotFoundException e) {
236+
return null;
237+
}
222238
}
223239
try {
224240
return findClassInternal(name);

src/test/java/org/codehaus/plexus/classworlds/realm/DefaultClassRealmTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@
1616
* limitations under the License.
1717
*/
1818

19+
import javax.naming.Context;
20+
import javax.naming.directory.DirContext;
21+
import javax.naming.directory.InitialDirContext;
22+
1923
import java.net.URL;
2024
import java.net.URLClassLoader;
2125
import java.util.Collections;
26+
import java.util.Hashtable;
2227
import java.util.concurrent.CountDownLatch;
2328

2429
import org.codehaus.classworlds.ClassRealmAdapter;
@@ -265,6 +270,39 @@ void testParallelDeadlockClassRealm() throws InterruptedException {
265270
}
266271
}
267272

273+
/**
274+
* Test that JDK internal classes from named modules (like com.sun.jndi.dns.DnsContextFactory)
275+
* can be properly accessed when loaded through ClassRealm. This is crucial for JNDI to work
276+
* correctly in Maven plugins.
277+
*
278+
* @see <a href="https://github.com/codehaus-plexus/plexus-classworlds/issues/XX">Issue XX</a>
279+
*/
280+
@Test
281+
void testLoadJdkModuleClassThroughJNDI() throws Exception {
282+
// Use system classloader as base to ensure JDK module classes can be loaded
283+
ClassRealm realm = new ClassRealm(new ClassWorld(), "test", ClassLoader.getSystemClassLoader());
284+
285+
// Set the thread's context classloader to the realm
286+
Thread currentThread = Thread.currentThread();
287+
ClassLoader originalClassLoader = currentThread.getContextClassLoader();
288+
try {
289+
currentThread.setContextClassLoader(realm);
290+
291+
// Try to instantiate DnsContextFactory via JNDI with explicit factory class name
292+
// This is how Netty uses JNDI under Windows
293+
Hashtable<String, String> env = new Hashtable<>();
294+
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
295+
env.put(Context.PROVIDER_URL, "dns:");
296+
297+
// This should succeed without IllegalAccessException
298+
DirContext ctx = new InitialDirContext(env);
299+
assertNotNull(ctx);
300+
ctx.close();
301+
} finally {
302+
currentThread.setContextClassLoader(originalClassLoader);
303+
}
304+
}
305+
268306
private void doOneDeadlockAttempt() throws InterruptedException {
269307
// Deadlock sample graciously ripped from http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html
270308
final ClassRealm cl1 = new ClassRealm(new ClassWorld(), "cl1", null);

0 commit comments

Comments
 (0)