8215359: InnocuousForkJoinWorkerThread.setContextClassLoader needlessly throws
Reviewed-by: martin, chegar, dholmes, reinhapa, alanb
--- 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");
}
}
}
--- 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());
}