Skip to content

Commit 3c6cd2e

Browse files
committed
Fix a race with two requests looking up a singleton JNDI resource
1 parent f59b31f commit 3c6cd2e

2 files changed

Lines changed: 42 additions & 20 deletions

File tree

java/org/apache/naming/NamingContext.java

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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.

webapps/docs/changelog.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@
218218
third-party library version information. (csutherl)
219219
</add>
220220
<!-- Entries for backport and removal before 12.0.0-M1 below this line -->
221+
<fix>
222+
Avoid a race condition with concurrent lookups for a singleton JNDI
223+
resource. (markt)
224+
</fix>
221225
</changelog>
222226
</subsection>
223227
<subsection name="Coyote">

0 commit comments

Comments
 (0)