This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new 4d8991e997 Fix a race with two requests looking up a singleton JNDI
resource
4d8991e997 is described below
commit 4d8991e99789751e5d6b7d5a4c008f9f249d6508
Author: Mark Thomas <[email protected]>
AuthorDate: Fri Jun 19 13:35:49 2026 +0100
Fix a race with two requests looking up a singleton JNDI resource
---
java/org/apache/naming/NamingContext.java | 58 ++++++++++++++++++++-----------
webapps/docs/changelog.xml | 8 +++++
2 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/java/org/apache/naming/NamingContext.java
b/java/org/apache/naming/NamingContext.java
index 7f680a43d3..5da0f2d522 100644
--- a/java/org/apache/naming/NamingContext.java
+++ b/java/org/apache/naming/NamingContext.java
@@ -518,28 +518,28 @@ public class NamingContext implements Context {
} else if (entry.type == NamingEntry.REFERENCE) {
try {
Object obj = null;
- if (!GRAAL) {
- obj = NamingManager.getObjectInstance(entry.value,
name, this, env);
- } else {
- // NamingManager.getObjectInstance would simply return
the reference here
- // Use the configured object factory to resolve it
directly if possible
- // Note: This may need manual constructor reflection
configuration
- Reference reference = (Reference) entry.value;
- String factoryClassName =
reference.getFactoryClassName();
- if (factoryClassName != null) {
- Class<?> factoryClass =
getClass().getClassLoader().loadClass(factoryClassName);
- ObjectFactory factory = (ObjectFactory)
factoryClass.getDeclaredConstructor().newInstance();
- obj = factory.getObjectInstance(entry.value, name,
this, env);
- }
- }
+ boolean singleton = false;
if (entry.value instanceof ResourceRef) {
- boolean singleton = Boolean.parseBoolean(
- (String) ((ResourceRef)
entry.value).get(ResourceRef.SINGLETON).getContent());
- if (singleton) {
- entry.type = NamingEntry.ENTRY;
- entry.value = obj;
+ // Only create singleton instances inside the sync
+ synchronized (entry) {
+ if (entry.value instanceof ResourceRef) {
+ singleton = Boolean.parseBoolean(
+ (String) ((ResourceRef)
entry.value).get(ResourceRef.SINGLETON).getContent());
+ if (singleton) {
+ obj = getObjectInstance(name, entry);
+ entry.type = NamingEntry.ENTRY;
+ entry.value = obj;
+ }
+ } else {
+ // Another thread has created the singleton
+ singleton = true;
+ obj = entry.value;
+ }
}
}
+ if (!singleton) {
+ obj = getObjectInstance(name, entry);
+ }
if (obj == null) {
throw new
NamingException(sm.getString("namingContext.failResolvingReference", name));
}
@@ -557,10 +557,28 @@ public class NamingContext implements Context {
return entry.value;
}
}
-
}
+ private Object getObjectInstance(Name name, NamingEntry entry) throws
Exception {
+ Object obj = null;
+ if (!GRAAL) {
+ obj = NamingManager.getObjectInstance(entry.value, name, this,
env);
+ } else {
+ // NamingManager.getObjectInstance would simply return the
reference here
+ // Use the configured object factory to resolve it directly if
possible
+ // Note: This may need manual constructor reflection configuration
+ Reference reference = (Reference) entry.value;
+ String factoryClassName = reference.getFactoryClassName();
+ if (factoryClassName != null) {
+ Class<?> factoryClass =
getClass().getClassLoader().loadClass(factoryClassName);
+ ObjectFactory factory = (ObjectFactory)
factoryClass.getDeclaredConstructor().newInstance();
+ obj = factory.getObjectInstance(entry.value, name, this, env);
+ }
+ }
+ return obj;
+ }
+
/**
* Binds a name to an object. All intermediate contexts and the target
context (that named by all but terminal
* atomic component of the name) must already exist.
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 5c449cc457..ffbe3deacf 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -108,6 +108,14 @@
issues do not "pop up" wrt. others).
-->
<section name="Tomcat 10.1.57 (schultz)" rtext="in development">
+ <subsection name="Catalina">
+ <changelog>
+ <fix>
+ Avoid a race condition with concurrent lookups for a singleton JNDI
+ resource. (markt)
+ </fix>
+ </changelog>
+ </subsection>
</section>
<section name="Tomcat 10.1.56 (schultz)" rtext="release in progress">
<subsection name="Catalina">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]