Skip to content

Commit 4b0ebc9

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 <6705942+slachiewicz@users.noreply.github.com>
1 parent 9a6e572 commit 4b0ebc9

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-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: 36 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,37 @@ void parallelDeadlockClassRealm() throws Exception {
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+
@Test
279+
void loadJdkModuleClassThroughJNDI() throws Exception {
280+
// Use system classloader as base to ensure JDK module classes can be loaded
281+
ClassRealm realm = new ClassRealm(new ClassWorld(), "test", ClassLoader.getSystemClassLoader());
282+
283+
// Set the thread's context classloader to the realm
284+
Thread currentThread = Thread.currentThread();
285+
ClassLoader originalClassLoader = currentThread.getContextClassLoader();
286+
try {
287+
currentThread.setContextClassLoader(realm);
288+
289+
// Try to instantiate DnsContextFactory via JNDI with explicit factory class name
290+
// This is how Netty uses JNDI under Windows
291+
Hashtable<String, String> env = new Hashtable<>();
292+
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
293+
env.put(Context.PROVIDER_URL, "dns:");
294+
295+
// This should succeed without IllegalAccessException
296+
DirContext ctx = new InitialDirContext(env);
297+
assertNotNull(ctx);
298+
ctx.close();
299+
} finally {
300+
currentThread.setContextClassLoader(originalClassLoader);
301+
}
302+
}
303+
268304
private void doOneDeadlockAttempt() throws InterruptedException {
269305
// Deadlock sample graciously ripped from http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html
270306
final ClassRealm cl1 = new ClassRealm(new ClassWorld(), "cl1", null);

0 commit comments

Comments
 (0)