Index: auto-depends/src/main/java/com/sun/hk2/component/SingletonInhabitant.java =================================================================== --- auto-depends/src/main/java/com/sun/hk2/component/SingletonInhabitant.java (revision 1646) +++ auto-depends/src/main/java/com/sun/hk2/component/SingletonInhabitant.java (working copy) @@ -41,6 +41,8 @@ import org.jvnet.hk2.component.Singleton; import org.jvnet.hk2.component.Inhabitant; +import java.util.concurrent.atomic.AtomicBoolean; + /** * Specialized implementation of {@link ScopedInhabitant} for {@link Singleton}. * @author Kohsuke Kawaguchi @@ -56,27 +58,33 @@ @SuppressWarnings("unchecked") @Override public T get(Inhabitant onBehalfOf) { - if (object==null) { - synchronized(this) { - if (object==null) { + if (object == null) { + synchronized (this) { + if (object == null) { + if (initializing) { + throw new ComponentException("problem initializing - cycle detected involving: " + this); + } + initializing = true; // object = womb.get(onBehalfOf); - // we do it in two steps in case there is an initialization error, we - // want to avoid recursing - object = womb.create(onBehalfOf); - try { - initializing = true; - womb.initialize(object, onBehalfOf); - } catch (Throwable e) { - object = null; - throw (e instanceof ComponentException) ? - (ComponentException)e : new ComponentException("problem initializing", e); - } finally { - initializing = false; - } + // we do it in two steps in case there is an initialization error, we + // want to avoid recursing + + // Create a temporary object to avoid the window when object != null && initializing = true + T newObject = womb.create(onBehalfOf); + try { + womb.initialize(newObject, onBehalfOf); + } catch (Throwable e) { + throw (e instanceof ComponentException) ? + (ComponentException) e : new ComponentException("problem initializing", e); + } finally { + initializing = false; + } + + // Because of the above try/catch, my understanding is compiler won't reorder + // assignment of newObject to object to before try block. + object = newObject; } } - } else if (initializing) { - throw new ComponentException("problem initializing - cycle detected involving: " + this); } return object; }