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]

Reply via email to