Author: markt
Date: Fri Oct 28 14:14:22 2011
New Revision: 1190339
URL: http://svn.apache.org/viewvc?rev=1190339&view=rev
Log:
Merge branch 'bug51744' into trunk
Modified:
tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java
tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
tomcat/trunk/java/org/apache/naming/NamingContext.java
tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java
tomcat/trunk/webapps/docs/config/context.xml
Modified: tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java Fri
Oct 28 14:14:22 2011
@@ -141,6 +141,13 @@ public class NamingContextListener
/**
+ * Determines if an attempt to write to a read-only context results in an
+ * exception or if the request is ignored.
+ */
+ private boolean exceptionOnFailedWrite = true;
+
+
+ /**
* The string manager for this package.
*/
protected static final StringManager sm =
@@ -149,6 +156,25 @@ public class NamingContextListener
// ------------------------------------------------------------- Properties
+ /**
+ * Returns whether or not an attempt to modify the JNDI context will
trigger
+ * an exception or if the request will be ignored.
+ */
+ public boolean getExceptionOnFailedWrite() {
+ return exceptionOnFailedWrite;
+ }
+
+
+ /**
+ * Controls whether or not an attempt to modify the JNDI context will
+ * trigger an exception or if the request will be ignored.
+ *
+ * @param exceptionOnFailedWrite The new value
+ */
+ public void setExceptionOnFailedWrite(boolean exceptionOnFailedWrite) {
+ this.exceptionOnFailedWrite = exceptionOnFailedWrite;
+ }
+
/**
* Return the "name" property.
@@ -214,6 +240,10 @@ public class NamingContextListener
log.debug("Bound " + container );
}
+ // Configure write when read-only behaviour
+ namingContext.setExceptionOnFailedWrite(
+ getExceptionOnFailedWrite());
+
// Setting the context in read/write mode
ContextAccessController.setWritable(getName(), container);
Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Fri Oct 28
14:14:22 2011
@@ -834,6 +834,7 @@ public class StandardContext extends Con
private boolean sendRedirectBody = false;
+ private boolean jndiExceptionOnFailedWrite = true;
// ----------------------------------------------------- Context Properties
@@ -2429,6 +2430,26 @@ public class StandardContext extends Con
// ------------------------------------------------------ Public Properties
+ /**
+ * Returns whether or not an attempt to modify the JNDI context will
trigger
+ * an exception or if the request will be ignored.
+ */
+ public boolean getJndiExceptionOnFailedWrite() {
+ return jndiExceptionOnFailedWrite;
+ }
+
+
+ /**
+ * Controls whether or not an attempt to modify the JNDI context will
+ * trigger an exception or if the request will be ignored.
+ *
+ * @param jndiExceptionOnFailedWrite
+ */
+ public void setJndiExceptionOnFailedWrite(
+ boolean jndiExceptionOnFailedWrite) {
+ this.jndiExceptionOnFailedWrite = jndiExceptionOnFailedWrite;
+ }
+
/**
* Return the Locale to character set mapper class for this Context.
@@ -4969,6 +4990,7 @@ public class StandardContext extends Con
if (getNamingContextListener() == null) {
NamingContextListener ncl = new NamingContextListener();
ncl.setName(getNamingContextName());
+ ncl.setExceptionOnFailedWrite(getJndiExceptionOnFailedWrite());
addLifecycleListener(ncl);
setNamingContextListener(ncl);
}
Modified: tomcat/trunk/java/org/apache/naming/NamingContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/NamingContext.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/naming/NamingContext.java (original)
+++ tomcat/trunk/java/org/apache/naming/NamingContext.java Fri Oct 28 14:14:22
2011
@@ -123,12 +123,21 @@ public class NamingContext implements Co
protected String name;
- // --------------------------------------------------------- Public Methods
+ /**
+ * Determines if an attempt to write to a read-only context results in an
+ * exception or if the request is ignored.
+ */
+ private boolean exceptionOnFailedWrite = true;
+ public boolean getExceptionOnFailedWrite() {
+ return exceptionOnFailedWrite;
+ }
+ public void setExceptionOnFailedWrite(boolean exceptionOnFailedWrite) {
+ this.exceptionOnFailedWrite = exceptionOnFailedWrite;
+ }
// -------------------------------------------------------- Context Methods
-
/**
* Retrieves the named object. If name is empty, returns a new instance
* of this context (which represents the same naming context as this
@@ -249,9 +258,11 @@ public class NamingContext implements Co
* @exception NamingException if a naming exception is encountered
*/
@Override
- public void unbind(Name name)
- throws NamingException {
- checkWritable();
+ public void unbind(Name name) throws NamingException {
+
+ if (!checkWritable()) {
+ return;
+ }
while ((!name.isEmpty()) && (name.get(0).length() == 0))
name = name.getSuffix(1);
@@ -465,10 +476,11 @@ public class NamingContext implements Co
* a context, or does not name a context of the appropriate type
*/
@Override
- public void destroySubcontext(Name name)
- throws NamingException {
+ public void destroySubcontext(Name name) throws NamingException {
- checkWritable();
+ if (!checkWritable()) {
+ return;
+ }
while ((!name.isEmpty()) && (name.get(0).length() == 0))
name = name.getSuffix(1);
@@ -533,13 +545,16 @@ public class NamingContext implements Co
* @exception NamingException if a naming exception is encountered
*/
@Override
- public Context createSubcontext(Name name)
- throws NamingException {
- checkWritable();
+ public Context createSubcontext(Name name) throws NamingException {
+ if (!checkWritable()) {
+ return null;
+ }
- Context newContext = new NamingContext(env, this.name);
+ NamingContext newContext = new NamingContext(env, this.name);
bind(name, newContext);
+ newContext.setExceptionOnFailedWrite(getExceptionOnFailedWrite());
+
return newContext;
}
@@ -744,7 +759,9 @@ public class NamingContext implements Co
*/
@Override
public void close() throws NamingException {
- checkWritable();
+ if (!checkWritable()) {
+ return;
+ }
env.clear();
}
@@ -866,7 +883,9 @@ public class NamingContext implements Co
protected void bind(Name name, Object obj, boolean rebind)
throws NamingException {
- checkWritable();
+ if (!checkWritable()) {
+ return;
+ }
while ((!name.isEmpty()) && (name.get(0).length() == 0))
name = name.getSuffix(1);
@@ -935,12 +954,16 @@ public class NamingContext implements Co
/**
* Throws a naming exception is Context is not writable.
*/
- protected void checkWritable()
- throws NamingException {
- if (!isWritable())
- throw new NamingException(sm.getString("namingContext.readOnly"));
+ protected boolean checkWritable() throws NamingException {
+ if (isWritable()) {
+ return true;
+ } else {
+ if (exceptionOnFailedWrite) {
+ throw new javax.naming.OperationNotSupportedException(
+ sm.getString("namingContext.readOnly"));
+ }
+ }
+ return false;
}
-
-
}
Modified: tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java
(original)
+++ tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java Fri
Oct 28 14:14:22 2011
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletReq
import javax.servlet.http.HttpServletResponse;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.junit.Test;
@@ -215,7 +216,17 @@ public class TestNamingContext extends T
}
@Test
- public void testBug51744() throws Exception {
+ public void testBug51744a() throws Exception {
+ doTestBug51744(true);
+ }
+
+ @Test
+ public void testBug51744b() throws Exception {
+ doTestBug51744(false);
+ }
+
+ private void doTestBug51744(boolean exceptionOnFailedWrite)
+ throws Exception {
Tomcat tomcat = getTomcatInstance();
tomcat.enableNaming();
@@ -223,6 +234,8 @@ public class TestNamingContext extends T
StandardContext ctx = (StandardContext)
tomcat.addContext("", System.getProperty("java.io.tmpdir"));
+ ctx.setJndiExceptionOnFailedWrite(exceptionOnFailedWrite);
+
// Map the test Servlet
Bug51744Servlet bug51744Servlet = new Bug51744Servlet();
Tomcat.addServlet(ctx, "bug51744Servlet", bug51744Servlet);
@@ -233,7 +246,10 @@ public class TestNamingContext extends T
ByteChunk bc = new ByteChunk();
int rc = getUrl("http://localhost:" + getPort() + "/", bc, null);
assertEquals(200, rc);
- assertEquals(Bug51744Servlet.EXPECTED, bc.toString());
+ assertTrue(bc.toString().contains(Bug51744Servlet.EXPECTED));
+ if (exceptionOnFailedWrite) {
+ assertTrue(bc.toString().contains(Bug51744Servlet.ERROR_MESSAGE));
+ }
}
public static final class Bug51744Servlet extends HttpServlet {
@@ -241,6 +257,7 @@ public class TestNamingContext extends T
private static final long serialVersionUID = 1L;
public static final String EXPECTED = "TestValue";
+ public static final String ERROR_MESSAGE = "Error";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
@@ -254,18 +271,13 @@ public class TestNamingContext extends T
Context env1 = (Context) ctx1.lookup("java:comp/env");
env1.addToEnvironment("TestName", EXPECTED);
- boolean error = false;
+ out.print(env1.getEnvironment().get("TestName"));
+
try {
env1.close();
} catch (NamingException ne) {
- error = true;
+ out.print(ERROR_MESSAGE);
}
- if (!error) {
- throw new ServletException(
- "No error when one was expected");
- }
-
- out.print(env1.getEnvironment().get("TestName"));
} catch (NamingException ne) {
ne.printStackTrace(out);
}
Modified: tomcat/trunk/webapps/docs/config/context.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Fri Oct 28 14:14:22 2011
@@ -657,6 +657,19 @@
not specified, the default value of <code>false</code> will be
used.</p>
</attribute>
+ <attribute name="jndiExceptionOnFailedWrite" required="false">
+ <p>If <code>true</code>, any attempt by an application to modify the
+ provided JNDI context with a call to bind(), unbind(),
+ createSubContext(), destroySubContext() or close() will trigger a
+ <code>javax.naming.OperationNotSupportedException</code> as required by
+ section EE.5.3.4 of the Java EE specification. This exception can be
+ disabled by setting this attribute to true in which case any calls to
+ modify the JNDI context will return <b>without</b> making any changes
+ and methods that return values will return <code>null</code>. If not
+ specified, the specification compliant default of <code>true</code>
will
+ be used.</p>
+ </attribute>
+
<attribute name="processTlds" required="false">
<p>Whether the context should process TLDs on startup. The default
is true. The false setting is intended for special cases
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]