Locking model of Introspector changed by fix of
bug 5102804. The code
(new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
is called under BEANINFO_CACHE lock by now, see getBeanInfo(Class) method.
This code can invoke 3rd-party code through findExplicitBeanInfo().
It is deadlock-prone to call 3rd-party code under some lock
and it should be avoided where it is possible.
See the following test-case. It shows how easily the mentioned
changes can result in a deadlock.
-------------------------------------------------
package problemofintrospector;
import java.awt.Point;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.SimpleBeanInfo;
public class TestCase {
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
// Get some BeanInfo in one thread
Introspector.getBeanInfo(CustomizedPoint.class, Object.class);
} catch (IntrospectionException iex) {}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
// Get some BeanInfo in another thread
Introspector.getBeanInfo(Point.class);
} catch (IntrospectionException iex) {}
}
});
t1.start();
Thread.sleep(500); // increase the chance of the deadlock
t2.start();
}
public static class CustomizedPoint extends Point {
}
public static class CustomizedPointBeanInfo extends SimpleBeanInfo {
private BeanInfo superInfo;
public CustomizedPointBeanInfo() {
try {
Thread.sleep(1000); // increase the chance of the deadlock
superInfo = Introspector.getBeanInfo(Point.class);
} catch (Exception ex) {
ex.printStackTrace();
}
}
// Real-life BeanInfo would contain some additional
// methods overriden and some work delegated to superInfo
// (the corresponding code is skipped because it is not
// necessary to reproduce the deadlock).
}
}
-------------------------------------------------
Note that the test-case doesn't run into deadlock on older JDK builds
(pre JDK 6 update 21 build 02), i.e., it is a regression. Also note
that this test-case is not an artifical one. It is based on a deadlock
that one of our users faces regularly while using NetBeans GUI Builder.