|
16 | 16 | * limitations under the License. |
17 | 17 | */ |
18 | 18 |
|
| 19 | +import javax.naming.Context; |
| 20 | +import javax.naming.directory.DirContext; |
| 21 | +import javax.naming.directory.InitialDirContext; |
| 22 | + |
19 | 23 | import java.net.URL; |
20 | 24 | import java.net.URLClassLoader; |
21 | 25 | import java.util.Collections; |
| 26 | +import java.util.Hashtable; |
22 | 27 | import java.util.concurrent.CountDownLatch; |
23 | 28 |
|
24 | 29 | import org.codehaus.classworlds.ClassRealmAdapter; |
@@ -265,6 +270,37 @@ void parallelDeadlockClassRealm() throws Exception { |
265 | 270 | } |
266 | 271 | } |
267 | 272 |
|
| 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 | + |
268 | 304 | private void doOneDeadlockAttempt() throws InterruptedException { |
269 | 305 | // Deadlock sample graciously ripped from http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html |
270 | 306 | final ClassRealm cl1 = new ClassRealm(new ClassWorld(), "cl1", null); |
|
0 commit comments