Details
Description
We've noticed occasional errors in our system that we were unable to reproduce reliably and couldn't track down easily (because of a unrelated) bug in some Sun code. A coworker has finally found the cause and produced the following analysis:
This method of org.codehaus.backport175.reader.bytecode.AnnotationReader
public static AnnotationReader getReaderFor(final ClassKey classKey) {
final AnnotationReader reader;
Object value = READERS.get(classKey);
if (value == null) {
synchronized (READERS)
} else
{ reader = (AnnotationReader) ((Reference)value).get(); } return reader;
}
contains an error. The AnnotationReader that is obtained in the line
reader = (AnnotationReader) ((Reference)value).get();
can be null, as the WeakReference content can be nullified by the VM if no other references to the content exist. In practice, this happens very seldom and non-deterministically. But as it sometimes does occur, null is returned in this case, which leads to a NullPointerException where the reader is used (in the Annotations class). A proposed fix is
public static AnnotationReader getReaderFor(final ClassKey classKey) {
AnnotationReader reader;
Object value = READERS.get(classKey);
if (value == null) {
synchronized (READERS)
} else {
reader = (AnnotationReader) ((Reference)value).get();
if (reader == null) {//WeakReference content can be null
synchronized (READERS)
}
}
return reader;
}
Thanks a lot for the analysis and the fix, I can see the potential problem now.
I will put this into the CVS HEAD and it will be part of the upcoming 1.1 release.