PAYARA-3121 Jersey Crashes for EJB Classes of Same Name (#3950)

* PAYARA-3121 Jersey Crashes for EJB Classes of Same Name

Signed-off-by: Gaurav Gupta <gaurav.gupta.jc@gmail.com>
diff --git a/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java b/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java
index 8a652e3..7e183d7 100644
--- a/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java
+++ b/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) [2018-2019] [Payara Foundation and/or its affiliates].
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -13,7 +14,6 @@
  *
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
-
 package org.glassfish.jersey.gf.ejb.internal;
 
 import java.lang.annotation.Annotation;
@@ -331,7 +331,7 @@
                 LocalizationMessages.EJB_INTERFACE_HANDLING_METHOD_LOOKUP_EXCEPTION(method, component, iFace), ex);
     }
 
-    private List<Class> remoteAndLocalIfaces(final Class<?> resourceClass) {
+    private static List<Class> remoteAndLocalIfaces(final Class<?> resourceClass) {
         final List<Class> allLocalOrRemoteIfaces = new LinkedList<>();
         if (resourceClass.isAnnotationPresent(Remote.class)) {
             allLocalOrRemoteIfaces.addAll(Arrays.asList(resourceClass.getAnnotation(Remote.class).value()));
@@ -357,18 +357,22 @@
         }
     }
 
-    private static Object lookup(InitialContext ic, Class<?> c, String name, EjbComponentProvider provider)
+    private static Object lookup(InitialContext ic, Class<?> rawType, String name, EjbComponentProvider provider)
             throws NamingException {
         try {
-            return lookupSimpleForm(ic, name, provider);
+            return lookupSimpleForm(ic, rawType, name, provider);
         } catch (NamingException ex) {
-            LOGGER.log(Level.WARNING, LocalizationMessages.EJB_CLASS_SIMPLE_LOOKUP_FAILED(c.getName()), ex);
+            LOGGER.log(Level.WARNING, LocalizationMessages.EJB_CLASS_SIMPLE_LOOKUP_FAILED(rawType.getName()), ex);
 
-            return lookupFullyQualifiedForm(ic, c, name, provider);
+            return lookupFullyQualifiedForm(ic, rawType, name, provider);
         }
     }
 
-    private static Object lookupSimpleForm(InitialContext ic, String name, EjbComponentProvider provider) throws NamingException {
+    private static Object lookupSimpleForm(
+            InitialContext ic,
+            Class<?> rawType,
+            String name,
+            EjbComponentProvider provider) throws NamingException {
         if (provider.libNames.isEmpty()) {
             String jndiName = "java:module/" + name;
             return ic.lookup(jndiName);
@@ -379,7 +383,7 @@
                 Object result;
                 try {
                     result = ic.lookup(jndiName);
-                    if (result != null) {
+                    if (result != null && isLookupInstanceValid(rawType, result)) {
                         return result;
                     }
                 } catch (NamingException e) {
@@ -390,19 +394,22 @@
         }
     }
 
-    private static Object lookupFullyQualifiedForm(InitialContext ic, Class<?> c, String name, EjbComponentProvider provider)
-            throws NamingException {
+    private static Object lookupFullyQualifiedForm(
+            InitialContext ic,
+            Class<?> rawType,
+            String name,
+            EjbComponentProvider provider) throws NamingException {
         if (provider.libNames.isEmpty()) {
-            String jndiName = "java:module/" + name + "!" + c.getName();
+            String jndiName = "java:module/" + name + "!" + rawType.getName();
             return ic.lookup(jndiName);
         } else {
             NamingException ne = null;
             for (String moduleName : provider.libNames) {
-                String jndiName = "java:app/" + moduleName + "/" + name + "!" + c.getName();
+                String jndiName = "java:app/" + moduleName + "/" + name + "!" + rawType.getName();
                 Object result;
                 try {
                     result = ic.lookup(jndiName);
-                    if (result != null) {
+                    if (result != null && isLookupInstanceValid(rawType, result)) {
                         return result;
                     }
                 } catch (NamingException e) {
@@ -412,4 +419,13 @@
             throw (ne != null) ? ne : new NamingException();
         }
     }
+
+    private static boolean isLookupInstanceValid(Class<?> rawType, Object result){
+        return rawType.isInstance(result)
+                                || remoteAndLocalIfaces(rawType)
+                                        .stream()
+                                        .filter(iface -> iface.isInstance(result))
+                                        .findAny()
+                                        .isPresent();
+    }
 }