Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2178821 | 5.0-pool | Unassigned | P3 | Closed | Won't Fix |
Run the following program under JDK 5:
---%<---
import java.util.logging.Logger;
public class TestLogManagerCleaner {
public static void main(String[] args) throws InterruptedException {
ThreadGroup g = new ThreadGroup("my group");
Thread t = new Thread(g, new Runnable() {
public void run() {
Logger.getAnonymousLogger().info("used the logger");
}
}, "my thread");
t.start();
t.join();
g.destroy();
System.exit(0);
}
}
---%<---
On Ubuntu 8.04, I get a nonzero VM exit status and a stack trace:
---%<---
java version "1.5.0_15"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_15-b04)
Java HotSpot(TM) Server VM (build 1.5.0_15-b04, mixed mode)
May 20, 2008 11:48:21 AM TestLogManagerCleaner$1 run
INFO: used the logger
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.ThreadGroup.add(ThreadGroup.java:856)
at java.lang.Thread.start(Thread.java:573)
at java.lang.Shutdown.runHooks(Shutdown.java:128)
at java.lang.Shutdown.sequence(Shutdown.java:173)
at java.lang.Shutdown.exit(Shutdown.java:218)
at java.lang.Runtime.exit(Runtime.java:90)
at java.lang.System.exit(System.java:869)
at TestLogManagerCleaner.main(TestLogManagerCleaner.java:13)
---%<---
I do not get this error in JDK 6 or 7, though I do not yet know why.
If I prepend a patched version of ThreadGroup.java
---%<---
// ... as before ...
if (destroyed) {
Object target = null;
try {
Field f = Thread.class.getDeclaredField("target");
f.setAccessible(true);
target = f.get(t);
} catch (Exception x) {
x.printStackTrace();
}
throw new IllegalThreadStateException("cannot add thread " + t + " of " + t.getClass() + " with target " + target + " to destroyed group " + this + " of " + getClass() + " with current threads " + Arrays.toString(threads));
}
// ... as before ...
---%<---
then I can see the real problem:
---%<---
...
Exception in thread "main" java.lang.IllegalThreadStateException: cannot add thread Thread[Thread-0,5,my group] of class java.util.logging.LogManager$Cleaner with target null to destroyed group java.lang.ThreadGroup[name=my group,maxpri=10] of class java.lang.ThreadGroup with current threads null
...
---%<---
It seems that LogManager's static block registers a VM shutdown hook from the calling thread's group. This is unsafe since there is no guarantee that this group is not an application thread group that might be destroyed before the VM exits.
Observed initially in NetBeans unit tests relating to thread groups. The test passes but the VM (and thus the Ant <junit> task) aborts:
[junit] Testsuite: org.netbeans.core.execution.CoreExecutionCompatibilityTest
[junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.238 sec
[junit]
[junit] Exception in thread "main" java.lang.IllegalThreadStateException
[junit] at java.lang.ThreadGroup.add(ThreadGroup.java:856)
[junit] at java.lang.Thread.start(Thread.java:573)
[junit] at java.lang.Shutdown.runHooks(Shutdown.java:128)
[junit] at java.lang.Shutdown.sequence(Shutdown.java:173)
[junit] at java.lang.Shutdown.exit(Shutdown.java:218)
[junit] at java.lang.Runtime.exit(Runtime.java:90)
[junit] at java.lang.System.exit(System.java:869)
[junit] at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:773)
[junit] Test org.netbeans.core.execution.CoreExecutionCompatibilityTest FAILED
Googling some key terms shows that this is not completely isolated:
http://tech.groups.yahoo.com/group/junitperf/message/84
---%<---
import java.util.logging.Logger;
public class TestLogManagerCleaner {
public static void main(String[] args) throws InterruptedException {
ThreadGroup g = new ThreadGroup("my group");
Thread t = new Thread(g, new Runnable() {
public void run() {
Logger.getAnonymousLogger().info("used the logger");
}
}, "my thread");
t.start();
t.join();
g.destroy();
System.exit(0);
}
}
---%<---
On Ubuntu 8.04, I get a nonzero VM exit status and a stack trace:
---%<---
java version "1.5.0_15"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_15-b04)
Java HotSpot(TM) Server VM (build 1.5.0_15-b04, mixed mode)
May 20, 2008 11:48:21 AM TestLogManagerCleaner$1 run
INFO: used the logger
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.ThreadGroup.add(ThreadGroup.java:856)
at java.lang.Thread.start(Thread.java:573)
at java.lang.Shutdown.runHooks(Shutdown.java:128)
at java.lang.Shutdown.sequence(Shutdown.java:173)
at java.lang.Shutdown.exit(Shutdown.java:218)
at java.lang.Runtime.exit(Runtime.java:90)
at java.lang.System.exit(System.java:869)
at TestLogManagerCleaner.main(TestLogManagerCleaner.java:13)
---%<---
I do not get this error in JDK 6 or 7, though I do not yet know why.
If I prepend a patched version of ThreadGroup.java
---%<---
// ... as before ...
if (destroyed) {
Object target = null;
try {
Field f = Thread.class.getDeclaredField("target");
f.setAccessible(true);
target = f.get(t);
} catch (Exception x) {
x.printStackTrace();
}
throw new IllegalThreadStateException("cannot add thread " + t + " of " + t.getClass() + " with target " + target + " to destroyed group " + this + " of " + getClass() + " with current threads " + Arrays.toString(threads));
}
// ... as before ...
---%<---
then I can see the real problem:
---%<---
...
Exception in thread "main" java.lang.IllegalThreadStateException: cannot add thread Thread[Thread-0,5,my group] of class java.util.logging.LogManager$Cleaner with target null to destroyed group java.lang.ThreadGroup[name=my group,maxpri=10] of class java.lang.ThreadGroup with current threads null
...
---%<---
It seems that LogManager's static block registers a VM shutdown hook from the calling thread's group. This is unsafe since there is no guarantee that this group is not an application thread group that might be destroyed before the VM exits.
Observed initially in NetBeans unit tests relating to thread groups. The test passes but the VM (and thus the Ant <junit> task) aborts:
[junit] Testsuite: org.netbeans.core.execution.CoreExecutionCompatibilityTest
[junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.238 sec
[junit]
[junit] Exception in thread "main" java.lang.IllegalThreadStateException
[junit] at java.lang.ThreadGroup.add(ThreadGroup.java:856)
[junit] at java.lang.Thread.start(Thread.java:573)
[junit] at java.lang.Shutdown.runHooks(Shutdown.java:128)
[junit] at java.lang.Shutdown.sequence(Shutdown.java:173)
[junit] at java.lang.Shutdown.exit(Shutdown.java:218)
[junit] at java.lang.Runtime.exit(Runtime.java:90)
[junit] at java.lang.System.exit(System.java:869)
[junit] at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:773)
[junit] Test org.netbeans.core.execution.CoreExecutionCompatibilityTest FAILED
Googling some key terms shows that this is not completely isolated:
http://tech.groups.yahoo.com/group/junitperf/message/84
- backported by
-
JDK-2178821 (thread) LogManager.Cleaner shutdown hook in JDK 5 can run in destroyed thread group
-
- Closed
-