This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new d04ac90aad Review "Fix the class loader used to check the type of a
JNDI..."
d04ac90aad is described below
commit d04ac90aadb512d39e33d58dd1e42efad7f6cdd4
Author: Mark Thomas <[email protected]>
AuthorDate: Fri Nov 6 17:27:52 2026 +0000
Review "Fix the class loader used to check the type of a JNDI..."
Restore support for array types.
Fix EJB 2.x lookups
---
.../catalina/core/NamingContextListener.java | 4 +-
java/org/apache/naming/factory/LookupFactory.java | 3 +-
.../apache/naming/factory/TestLookupFactory.java | 81 +++++++++++++++++++++-
3 files changed, 84 insertions(+), 4 deletions(-)
diff --git a/java/org/apache/catalina/core/NamingContextListener.java
b/java/org/apache/catalina/core/NamingContextListener.java
index fce91c0511..3dfb781b41 100644
--- a/java/org/apache/catalina/core/NamingContextListener.java
+++ b/java/org/apache/catalina/core/NamingContextListener.java
@@ -646,10 +646,12 @@ public class NamingContextListener implements
LifecycleListener, PropertyChangeL
// interface which the application expects is used as the type of a
// lookup reference. No type is given when the descriptor names no
// interface, which leaves the type of the looked up object unchecked.
+ // An EJB 2.x reference looks up a home object, so prefer its home
+ // interface when present. Otherwise use the EJB 3.x business
interface.
String lookupName = ejb.getLookupName();
Reference ref = null;
if (lookupName != null && !lookupName.isEmpty()) {
- String beanType = ejb.getRemote() != null ? ejb.getRemote() :
ejb.getHome();
+ String beanType = ejb.getHome() != null ? ejb.getHome() :
ejb.getRemote();
ref = new LookupRef(beanType, lookupName);
}
diff --git a/java/org/apache/naming/factory/LookupFactory.java
b/java/org/apache/naming/factory/LookupFactory.java
index 4d8499e8a2..504d727357 100644
--- a/java/org/apache/naming/factory/LookupFactory.java
+++ b/java/org/apache/naming/factory/LookupFactory.java
@@ -138,7 +138,8 @@ public class LookupFactory implements ObjectFactory {
ClassLoader tcl =
Thread.currentThread().getContextClassLoader();
try {
if (tcl != null) {
- clazz = tcl.loadClass(className);
+ // Class.forName also accepts array class names,
unlike ClassLoader.loadClass.
+ clazz = Class.forName(className, false, tcl);
} else {
clazz = Class.forName(className);
}
diff --git a/test/org/apache/naming/factory/TestLookupFactory.java
b/test/org/apache/naming/factory/TestLookupFactory.java
index 3673b2c9f3..067df7c208 100644
--- a/test/org/apache/naming/factory/TestLookupFactory.java
+++ b/test/org/apache/naming/factory/TestLookupFactory.java
@@ -18,6 +18,7 @@ package org.apache.naming.factory;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -51,6 +52,7 @@ import org.apache.tomcat.util.descriptor.web.ContextEjb;
public class TestLookupFactory extends TomcatBaseTest {
private static final String MARKER_CLASS = "tester.Marker";
+ private static final String MARKER_HOME = "tester.MarkerHome";
private ClassLoader originalContextClassLoader;
@@ -67,6 +69,37 @@ public class TestLookupFactory extends TomcatBaseTest {
}
+ @Test
+ public void testReferenceArrayTypeIsLoaded() throws Exception {
+ startWebapp();
+ checkArrayLookup(new String[] { "value" });
+ }
+
+
+ @Test
+ public void testPrimitiveArrayTypeIsLoaded() throws Exception {
+ startWebapp();
+ checkArrayLookup(new int[] { 1 });
+ }
+
+
+ @Test
+ public void testWebappLocalArrayTypeIsLoaded() throws Exception {
+ TesterWebapp webapp = startWebapp();
+ checkArrayLookup(Array.newInstance(webapp.marker().getClass(), 1));
+ }
+
+
+ private void checkArrayLookup(Object array) throws Exception {
+ Context container = ContextBindings.getClassLoader();
+ container.bind("comp/env/array", array);
+ container.bind("comp/env/ref", new
LookupRef(array.getClass().getName(), "java:comp/env/array"));
+
+ Object found = new
javax.naming.InitialContext().lookup("java:comp/env/ref");
+ Assert.assertSame(array, found);
+ }
+
+
@Test
public void testEjbLookupRefIsCheckedAgainstTheBeanInterface() throws
Exception {
TesterWebapp webapp = startWebapp();
@@ -86,6 +119,47 @@ public class TestLookupFactory extends TomcatBaseTest {
}
+ @Test
+ public void testEjbLookupRefPrefersHomeInterface() throws Exception {
+ TesterWebapp webapp = startWebapp();
+
+ ContextEjb ejb = new ContextEjb();
+ ejb.setName("ejb");
+ ejb.setType("Session");
+ ejb.setLookupName("java:comp/env/target");
+ ejb.setHome(MARKER_HOME);
+ // A home object implements the home interface, not the remote
component interface.
+ ejb.setRemote(CharSequence.class.getName());
+ webapp.listener().addEjb(ejb);
+
+ Object found = new
javax.naming.InitialContext().lookup("java:comp/env/ejb");
+ Assert.assertSame(webapp.marker(), found);
+ }
+
+
+ @Test
+ public void testEjbLookupRefRejectsWrongHomeInterface() throws Exception {
+ TesterWebapp webapp = startWebapp();
+
+ ContextEjb ejb = new ContextEjb();
+ ejb.setName("ejb");
+ ejb.setType("Session");
+ ejb.setLookupName("java:comp/env/target");
+ ejb.setHome(CharSequence.class.getName());
+ // Matching the remote type must not bypass a mismatched home type.
+ ejb.setRemote(MARKER_CLASS);
+ webapp.listener().addEjb(ejb);
+
+ try {
+ Object found = new
javax.naming.InitialContext().lookup("java:comp/env/ejb");
+ Assert.fail("The reference of the wrong home type was returned: "
+ found);
+ } catch (javax.naming.NamingException e) {
+ Assert.assertTrue("The wrong failure was reported: " +
e.getMessage(),
+ e.getMessage().contains("expected to be of type"));
+ }
+ }
+
+
@Test
public void testTypeMismatchIsStillReported() throws Exception {
startWebapp();
@@ -172,11 +246,14 @@ public class TestLookupFactory extends TomcatBaseTest {
Files.createDirectories(classes);
Path source = new File(docBase, "tester/Marker.java").toPath();
Files.createDirectories(source.getParent());
- Files.write(source, ("package tester;\npublic class Marker
{\n}\n".getBytes(StandardCharsets.UTF_8)));
+ Files.writeString(source, "package tester;\npublic class Marker
implements MarkerHome {\n}\n",
+ StandardCharsets.UTF_8);
+ Path homeSource = source.resolveSibling("MarkerHome.java");
+ Files.writeString(homeSource, "package tester;\npublic interface
MarkerHome {\n}\n", StandardCharsets.UTF_8);
ByteArrayOutputStream compilerOutput = new ByteArrayOutputStream();
@SuppressWarnings("null")
int result = compiler.run(null, compilerOutput, compilerOutput, "-d",
classes.toString(),
- source.toString());
+ source.toString(), homeSource.toString());
Assert.assertEquals("The class of the web application could not be
compiled: " + compilerOutput, 0, result);
Tomcat tomcat = getTomcatInstance();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]