@@ -518,28 +518,28 @@ protected Object lookup(Name name, boolean resolveLinks) throws NamingException
518518 } else if (entry .type == NamingEntry .REFERENCE ) {
519519 try {
520520 Object obj = null ;
521- if (!GRAAL ) {
522- obj = NamingManager .getObjectInstance (entry .value , name , this , env );
523- } else {
524- // NamingManager.getObjectInstance would simply return the reference here
525- // Use the configured object factory to resolve it directly if possible
526- // Note: This may need manual constructor reflection configuration
527- Reference reference = (Reference ) entry .value ;
528- String factoryClassName = reference .getFactoryClassName ();
529- if (factoryClassName != null ) {
530- Class <?> factoryClass = getClass ().getClassLoader ().loadClass (factoryClassName );
531- ObjectFactory factory = (ObjectFactory ) factoryClass .getDeclaredConstructor ().newInstance ();
532- obj = factory .getObjectInstance (entry .value , name , this , env );
533- }
534- }
521+ boolean singleton = false ;
535522 if (entry .value instanceof ResourceRef ) {
536- boolean singleton = Boolean .parseBoolean (
537- (String ) ((ResourceRef ) entry .value ).get (ResourceRef .SINGLETON ).getContent ());
538- if (singleton ) {
539- entry .type = NamingEntry .ENTRY ;
540- entry .value = obj ;
523+ // Only create singleton instances inside the sync
524+ synchronized (entry ) {
525+ if (entry .value instanceof ResourceRef ) {
526+ singleton = Boolean .parseBoolean (
527+ (String ) ((ResourceRef ) entry .value ).get (ResourceRef .SINGLETON ).getContent ());
528+ if (singleton ) {
529+ obj = getObjectInstance (name , entry );
530+ entry .type = NamingEntry .ENTRY ;
531+ entry .value = obj ;
532+ }
533+ } else {
534+ // Another thread has created the singleton
535+ singleton = true ;
536+ obj = entry .value ;
537+ }
541538 }
542539 }
540+ if (!singleton ) {
541+ obj = getObjectInstance (name , entry );
542+ }
543543 if (obj == null ) {
544544 throw new NamingException (sm .getString ("namingContext.failResolvingReference" , name ));
545545 }
@@ -557,10 +557,28 @@ protected Object lookup(Name name, boolean resolveLinks) throws NamingException
557557 return entry .value ;
558558 }
559559 }
560-
561560 }
562561
563562
563+ private Object getObjectInstance (Name name , NamingEntry entry ) throws Exception {
564+ Object obj = null ;
565+ if (!GRAAL ) {
566+ obj = NamingManager .getObjectInstance (entry .value , name , this , env );
567+ } else {
568+ // NamingManager.getObjectInstance would simply return the reference here
569+ // Use the configured object factory to resolve it directly if possible
570+ // Note: This may need manual constructor reflection configuration
571+ Reference reference = (Reference ) entry .value ;
572+ String factoryClassName = reference .getFactoryClassName ();
573+ if (factoryClassName != null ) {
574+ Class <?> factoryClass = getClass ().getClassLoader ().loadClass (factoryClassName );
575+ ObjectFactory factory = (ObjectFactory ) factoryClass .getDeclaredConstructor ().newInstance ();
576+ obj = factory .getObjectInstance (entry .value , name , this , env );
577+ }
578+ }
579+ return obj ;
580+ }
581+
564582 /**
565583 * Binds a name to an object. All intermediate contexts and the target context (that named by all but terminal
566584 * atomic component of the name) must already exist.
0 commit comments