mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-15 13:02:19 +00:00
Fix [JENKINS-49206] by ensuring Timer threads get standard classloader (#3272)
* Fix [JENKINS-49206] by ensuring Timer threads get standard classloader * Refactor to better fit in with existing ThreadFactor utils * Fix javadocs
This commit is contained in:
1 parent
6cefcf17a8
commit
2a6fc653ee
3 files changed
+84
-2
No files matched your search
@@ -1,12 +1,18 @@
|
||||
package jenkins.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import hudson.triggers.SafeTimerTask;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.jvnet.hudson.test.Issue;
|
||||
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class TimerTest {
|
||||
@@ -44,4 +50,52 @@ public class TimerTest {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch two tasks which can only complete
|
||||
* by running doRun() concurrently.
|
||||
*/
|
||||
@Test
|
||||
@Issue("JENKINS-49206")
|
||||
public void timerBogusClassloader() throws Exception {
|
||||
final int threadCount = 10; // Twice Timer pool size to ensure we end up creating at least one new thread
|
||||
final CountDownLatch startLatch = new CountDownLatch(threadCount);
|
||||
|
||||
final ClassLoader[] contextClassloaders = new ClassLoader[threadCount];
|
||||
ScheduledFuture[] futures = new ScheduledFuture[threadCount];
|
||||
final ClassLoader bogusClassloader = new GroovyClassLoader();
|
||||
|
||||
Runnable timerTest = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(bogusClassloader);
|
||||
ScheduledExecutorService exec = Timer.get();
|
||||
for (int i=0; i<threadCount; i++) {
|
||||
final int j = i;
|
||||
futures[j] = exec.schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
startLatch.countDown();
|
||||
contextClassloaders[j] = Thread.currentThread().getContextClassLoader();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
};
|
||||
|
||||
Thread t = new Thread(timerTest);
|
||||
t.run();
|
||||
t.join(1000L);
|
||||
|
||||
for (int i=0; i<threadCount; i++) {
|
||||
futures[i].get();
|
||||
Assert.assertEquals(Timer.class.getClassLoader(), contextClassloaders[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user