# HG changeset patch # User dl # Date 1550258281 28800 # Node ID 709631caffa3bcf1f9f9c81121d31c28d0ec2e61 # Parent 4f1040869d2408c21a6a3e352c0eb1dc59ffd17e 8215359: InnocuousForkJoinWorkerThread.setContextClassLoader needlessly throws Reviewed-by: martin, chegar, dholmes, reinhapa, alanb diff -r 4f1040869d24 -r 709631caffa3 src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Fri Feb 15 11:18:01 2019 -0800 +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Fri Feb 15 11:18:01 2019 -0800 @@ -236,7 +236,8 @@ @Override // paranoically public void setContextClassLoader(ClassLoader cl) { - throw new SecurityException("setContextClassLoader"); + if (cl != null && ClassLoader.getSystemClassLoader() != cl) + throw new SecurityException("setContextClassLoader"); } } } diff -r 4f1040869d24 -r 709631caffa3 test/jdk/java/util/concurrent/tck/ForkJoinPool9Test.java --- a/test/jdk/java/util/concurrent/tck/ForkJoinPool9Test.java Fri Feb 15 11:18:01 2019 -0800 +++ b/test/jdk/java/util/concurrent/tck/ForkJoinPool9Test.java Fri Feb 15 11:18:01 2019 -0800 @@ -38,6 +38,8 @@ import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.Future; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Stream; import junit.framework.Test; import junit.framework.TestSuite; @@ -67,21 +69,33 @@ .findVarHandle(Thread.class, "contextClassLoader", ClassLoader.class); ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); boolean haveSecurityManager = (System.getSecurityManager() != null); - CountDownLatch taskStarted = new CountDownLatch(1); + CountDownLatch runInCommonPoolStarted = new CountDownLatch(1); + ClassLoader classLoaderDistinctFromSystemClassLoader + = ClassLoader.getPlatformClassLoader(); + assertNotSame(classLoaderDistinctFromSystemClassLoader, + systemClassLoader); Runnable runInCommonPool = () -> { - taskStarted.countDown(); + runInCommonPoolStarted.countDown(); assertTrue(ForkJoinTask.inForkJoinPool()); - assertSame(ForkJoinPool.commonPool(), - ForkJoinTask.getPool()); - assertSame(systemClassLoader, - Thread.currentThread().getContextClassLoader()); - assertSame(systemClassLoader, - CCL.get(Thread.currentThread())); + assertSame(ForkJoinPool.commonPool(), ForkJoinTask.getPool()); + Thread currentThread = Thread.currentThread(); + + Stream.of(systemClassLoader, null).forEach(cl -> { + if (ThreadLocalRandom.current().nextBoolean()) + // should always be permitted, without effect + currentThread.setContextClassLoader(cl); + }); + + Stream.of(currentThread.getContextClassLoader(), + (ClassLoader) CCL.get(currentThread)) + .forEach(cl -> assertTrue(cl == systemClassLoader || cl == null)); + if (haveSecurityManager) assertThrows( SecurityException.class, () -> System.getProperty("foo"), - () -> Thread.currentThread().setContextClassLoader(null)); + () -> currentThread.setContextClassLoader( + classLoaderDistinctFromSystemClassLoader)); // TODO ? // if (haveSecurityManager // && Thread.currentThread().getClass().getSimpleName() @@ -91,7 +105,7 @@ Future f = ForkJoinPool.commonPool().submit(runInCommonPool); // Ensure runInCommonPool is truly running in the common pool, // by giving this thread no opportunity to "help" on get(). - await(taskStarted); + await(runInCommonPoolStarted); assertNull(f.get()); }