Bug 15488

Summary: BeanInfoManager uses double-checked locking
Product: Taglibs Reporter: Christopher Schultz <schultz>
Component: Unknown TaglibAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED INVALID    
Severity: normal    
Priority: P3    
Version: 1.0   
Target Milestone: ---   
Hardware: Other   
OS: other   

Description Christopher Schultz 2002-12-18 15:42:22 UTC
BeanInfoManager uses double-checked locking in checkInitialized() method.

  void checkInitialized (Logger pLogger)
    throws ELException
  {
    if (!mInitialized) {
      synchronized (this) {
	if (!mInitialized) {
	  initialize (pLogger);
	  mInitialized = true;
	}
      }
    }
  }

DCL is not guarenteed to work on any particular VM, although it probably does on
many.

References:
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

This seems to have all the reasons in a single, concise page. It also contains
some other of the references that I would have included here.

Solution:
Simply make the method itself synchronized. Performance degrades, but
correctness improves :)

  synchronized void checkInitialized (Logger pLogger)
    throws ELException
  {
     if (!mInitialized) {
	  initialize (pLogger);
	  mInitialized = true;
     }
  }
Comment 1 Christopher Schultz 2002-12-18 15:58:33 UTC
Update: after reading the reserence that I actually included as part of the bug,
I believe that since the DCL uses a boolean as the value to be double-checked,
it will work and is not a bug.

Can someone take a look and confirm that?
Comment 2 Shawn Bayern 2002-12-18 16:34:19 UTC
I believe your latter assessment is correct; it should work for booleans, 
since reads from and writes to booleans are atomic (as they're less than 32 
bits long).

By the way, which class (by fully qualified package name) in which taglib are 
you referring to?  This bug was filed under "Unknown Taglib"; I'm responding 
based on the assumption that you're referring to the EL implementation 
currently in the Standard Taglib.
Comment 3 Christopher Schultz 2002-12-18 16:42:53 UTC
Sorry. Yes, I'm talking about the EL implementation.

org.apache.taglibs.standard.lang.jstl.BeanInfoManager

An unrelated question about the BeanManager: A colleague of mine was using a
class called Component and it blew up when used within the EL because the
Introspector was finding a BeanInfo for java.awt.Component and no BeanInfo for
his Component class.

It took forever to figure it out. It looks like possible solutions are:

1. Write a BeanInfo class for his class, as well as for all other classes he
uses with the JSTL
2. Set the 'bean info path' to nothing to force the use of reflection
3. Hack the BeanInfoManager to use IGNORE_ALL_BEANINFO when incoking the
Introspector.

None of these seem like great ideas. Got any of your own? >:|