From: markt Date: Thu, 4 Nov 2010 17:59:20 +0000 (+0000) Subject: https://issues.apache.org/bugzilla/show_bug.cgi?id=50159 X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=4a0a882d3569c9a0f21bee336d66ba31b200734a;p=tomcat7.0 https://issues.apache.org/bugzilla/show_bug.cgi?id=50159 Add a new attribute for elements, singleton that controls whether or not a new object is created every time a JNDI lookup is performed to obtain the resource. The default value is true, which will return the same instance of the resource in every JNDI lookup. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1031112 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/core/NamingContextListener.java b/java/org/apache/catalina/core/NamingContextListener.java index 1e2ff4eca..da9ad5eee 100644 --- a/java/org/apache/catalina/core/NamingContextListener.java +++ b/java/org/apache/catalina/core/NamingContextListener.java @@ -849,7 +849,8 @@ public class NamingContextListener /** * Set the specified local EJBs in the naming context. */ - public void addLocalEjb(ContextLocalEjb localEjb) { + public void addLocalEjb( + @SuppressWarnings("unused") ContextLocalEjb localEjb) { // NO-OP } @@ -992,7 +993,8 @@ public class NamingContextListener // Create a reference to the resource. Reference ref = new ResourceRef (resource.getType(), resource.getDescription(), - resource.getScope(), resource.getAuth()); + resource.getScope(), resource.getAuth(), + resource.getSingleton()); // Adding the additional parameters, if any Iterator params = resource.listProperties(); while (params.hasNext()) { diff --git a/java/org/apache/catalina/deploy/ContextResource.java b/java/org/apache/catalina/deploy/ContextResource.java index e53eea2ad..237e5832f 100644 --- a/java/org/apache/catalina/deploy/ContextResource.java +++ b/java/org/apache/catalina/deploy/ContextResource.java @@ -65,6 +65,21 @@ public class ContextResource extends ResourceBase { } + /** + * Is this resource known to be a singleton resource. The default value is + * true since this is what users expect although the JavaEE spec implies + * that the default should be false. + */ + private boolean singleton = true; + + public boolean getSingleton() { + return singleton; + } + + public void setSingleton(boolean singleton) { + this.singleton = singleton; + } + // --------------------------------------------------------- Public Methods diff --git a/java/org/apache/naming/NamingContext.java b/java/org/apache/naming/NamingContext.java index 107bc401c..7e419e713 100644 --- a/java/org/apache/naming/NamingContext.java +++ b/java/org/apache/naming/NamingContext.java @@ -825,6 +825,13 @@ public class NamingContext implements Context { try { Object obj = NamingManager.getObjectInstance (entry.value, name, this, env); + boolean singleton = Boolean.parseBoolean( + (String) ((ResourceRef) entry.value).get( + "singleton").getContent()); + if (singleton) { + entry.type = NamingEntry.ENTRY; + entry.value = obj; + } return obj; } catch (NamingException e) { throw e; diff --git a/java/org/apache/naming/ResourceRef.java b/java/org/apache/naming/ResourceRef.java index 48f569f41..8774843d0 100644 --- a/java/org/apache/naming/ResourceRef.java +++ b/java/org/apache/naming/ResourceRef.java @@ -32,13 +32,13 @@ import javax.naming.StringRefAddr; * @version $Id$ */ -public class ResourceRef - extends Reference { +public class ResourceRef extends Reference { + private static final long serialVersionUID = 1L; + // -------------------------------------------------------------- Constants - /** * Default factory for this reference. */ @@ -64,6 +64,11 @@ public class ResourceRef public static final String AUTH = "auth"; + /** + * Is this resource a singleton + */ + public static final String SINGLETON = "singleton"; + // ----------------------------------------------------------- Constructors @@ -75,8 +80,8 @@ public class ResourceRef * @param auth Resource authentication */ public ResourceRef(String resourceClass, String description, - String scope, String auth) { - this(resourceClass, description, scope, auth, null, null); + String scope, String auth, boolean singleton) { + this(resourceClass, description, scope, auth, singleton, null, null); } @@ -88,8 +93,8 @@ public class ResourceRef * @param auth Resource authentication */ public ResourceRef(String resourceClass, String description, - String scope, String auth, String factory, - String factoryLocation) { + String scope, String auth, boolean singleton, + String factory, String factoryLocation) { super(resourceClass, factory, factoryLocation); StringRefAddr refAddr = null; if (description != null) { @@ -104,6 +109,9 @@ public class ResourceRef refAddr = new StringRefAddr(AUTH, auth); add(refAddr); } + // singleton is a boolean so slightly different handling + refAddr = new StringRefAddr(SINGLETON, Boolean.toString(singleton)); + add(refAddr); } diff --git a/test/org/apache/naming/resources/TestNamingContext.java b/test/org/apache/naming/resources/TestNamingContext.java index 33daf04ff..d374f51cd 100644 --- a/test/org/apache/naming/resources/TestNamingContext.java +++ b/test/org/apache/naming/resources/TestNamingContext.java @@ -37,7 +37,15 @@ import org.apache.tomcat.util.buf.ByteChunk; public class TestNamingContext extends TomcatBaseTest { - public void testLookup() throws Exception { + public void testLookupSingletonResource() throws Exception { + doTestLookup(true); + } + + public void testLookupNonSingletonResource() throws Exception { + doTestLookup(false); + } + + public void doTestLookup(boolean useSingletonResource) throws Exception { Tomcat tomcat = getTomcatInstance(); tomcat.enableNaming(); @@ -50,6 +58,7 @@ public class TestNamingContext extends TomcatBaseTest { cr.setName("list/foo"); cr.setType("org.apache.naming.resources.TesterObject"); cr.setProperty("factory", "org.apache.naming.resources.TesterFactory"); + cr.setSingleton(useSingletonResource); ctx.getNamingResources().addResource(cr); // Map the test Servlet @@ -60,7 +69,14 @@ public class TestNamingContext extends TomcatBaseTest { tomcat.start(); ByteChunk bc = getUrl("http://localhost:" + getPort() + "/"); - assertEquals("OK", bc.toString()); + + String expected; + if (useSingletonResource) { + expected = "EQUAL"; + } else { + expected = "NOTEQUAL"; + } + assertEquals(expected, bc.toString()); } @@ -80,9 +96,9 @@ public class TestNamingContext extends TomcatBaseTest { Object obj1 = ctx.lookup("java:comp/env/list/foo"); Object obj2 = ctx.lookup("java:comp/env/list/foo"); if (obj1 == obj2) { - out.print("FAIL"); + out.print("EQUAL"); } else { - out.print("OK"); + out.print("NOTEQUAL"); } } catch (NamingException ne) { ne.printStackTrace(out); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 8c73b77e6..0a1b64ac1 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -73,6 +73,13 @@ 50157: Ensure MapperListener is only added to a container object once. (markt) + + 50159: Add a new attribute for <Resource> + elements, singleton, that controls whether or not a new + object is created every time a JNDI lookup is performed to obtain the + resource. The default value is true, which will return the + same instance of the resource in every JNDI lookup. (markt) + Improve debug logging for MapperListener registration. (markt) diff --git a/webapps/docs/config/context.xml b/webapps/docs/config/context.xml index ea87ff0aa..7bef4d403 100644 --- a/webapps/docs/config/context.xml +++ b/webapps/docs/config/context.xml @@ -878,6 +878,16 @@ connections are assumed to be shareable.

+ +

Specify whether this resource definition is for a singleton resource, + i.e. one where there is only a single instance of the resource. If this + attribute is true, multiple JNDI lookups for this resource + will return the same object. If this attribute is false, + multiple JNDI lookups for this resource will return different objects. + The value of this attribute must be true or + false. By default, this attribute is true.

+
+

The fully qualified Java class name expected by the web application when it performs a lookup for this resource.