[jboss-cvs] JBossAS SVN: r100971 - in projects/ejb3/components/nointerface/trunk: impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Feb 15 10:34:32 EST 2010


Author: jaikiran
Date: 2010-02-15 10:34:31 -0500 (Mon, 15 Feb 2010)
New Revision: 100971

Added:
   projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/JavassistInvocationHandlerAdapter.java
   projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/NoInterfaceViewMethodFilter.java
   projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/
   projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/Contact.java
   projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactBean.java
   projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactManager.java
   projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/WrapperBean.java
   projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/unit/
   projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/unit/ClassLoadingUnitTestCase.java
Modified:
   projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java
Log:
EJBTHREE-2014 Rewrote the nointerface view proxy factory (to simplify) the proxy creation using the javassist.util.proxy.ProxyFactory API. This also fixes the classloading issue

Added: projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/JavassistInvocationHandlerAdapter.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/JavassistInvocationHandlerAdapter.java	                        (rev 0)
+++ projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/JavassistInvocationHandlerAdapter.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -0,0 +1,74 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.impl.view;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import javassist.util.proxy.MethodHandler;
+
+/**
+ * {@link JavassistInvocationHandlerAdapter} is an implementation of Javassist {@link MethodHandler}
+ * and is responsible for forwarding the method invocations to a instance of {@link java.lang.reflect.InvocationHandler}
+ *
+ * @see MethodHandler
+ * @see InvocationHandler
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class JavassistInvocationHandlerAdapter implements MethodHandler
+{
+
+   /**
+    * The invocation handler to which the method invocations will be forwarded to
+    */
+   private InvocationHandler invocationHandler;
+
+   /**
+    * Creates a {@link JavassistInvocationHandlerAdapter} for an {@link InvocationHandler}
+    * @param invocationHandler The invocation handler
+    * @throws IllegalArgumentException If the passed <code>invocationHandler</code> is null
+    */
+   public JavassistInvocationHandlerAdapter(InvocationHandler invocationHandler)
+   {
+      if (invocationHandler == null)
+      {
+         throw new IllegalArgumentException(this.getClass().getName() + " cannot be created out of a null "
+               + InvocationHandler.class.getName());
+      }
+      this.invocationHandler = invocationHandler;
+   }
+
+   /**
+    * Lets the {@link InvocationHandler} instance, which was passed to {@link #JavassistInvocationHandlerAdapter(InvocationHandler)} 
+    * handle the method invocation.
+    * 
+    * @see javassist.util.proxy.MethodHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.reflect.Method, java.lang.Object[])
+    */
+   @Override
+   public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
+   {
+      // let the invocation handler take care of the call
+      return this.invocationHandler.invoke(self, thisMethod, args);
+   }
+
+}

Added: projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/NoInterfaceViewMethodFilter.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/NoInterfaceViewMethodFilter.java	                        (rev 0)
+++ projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/NoInterfaceViewMethodFilter.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -0,0 +1,158 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.impl.view;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.MethodHandler;
+
+/**
+ * A {@link NoInterfaceViewMethodFilter} is responsible for deciding whether
+ * a method invoked on a nointerface view proxy is to be handled by the 
+ * underlying invocation handler. 
+ * <p>
+ *  The {@link NoInterfaceViewMethodFilter#isHandled(Method)} checks for the method attributes to
+ *  decide whether the method should be skipped by the proxy's {@link MethodHandler} or whether it should be handled
+ *  by the proxy's {@link MethodHandler}
+ * </p>
+ *
+ * @see MethodHandler
+ * @see MethodFilter
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class NoInterfaceViewMethodFilter implements MethodFilter
+{
+
+   /**
+    * Returns true if the {@link Method} <code>m</code> should be handled 
+    * by the nointerface view proxy's invocation handler.
+    * 
+    * <p>
+    *   Returns false if 
+    *   <ul>
+    *       <li><code>m</code> is *not* public</li>
+    *       <li><code>m</code> is static</li>
+    *       <li><code>m</code> is final</li>
+    *       <li><code>m</code> is native</li> 
+    *   </ul>
+    * </p>
+    * @see javassist.util.proxy.MethodFilter#isHandled(java.lang.reflect.Method)
+    */
+   @Override
+   public boolean isHandled(Method m)
+   {
+      // We handle only public, non-static, non-final methods
+      if (!isPublic(m))
+      {
+         // it's not a public method
+         return false;
+      }
+      if (isFinal(m))
+      {
+         // it's a final method
+         return false;
+      }
+      if (isStatic(m))
+      {
+         // it's a static method
+         return false;
+      }
+      if (isNative(m))
+      {
+         // it's a native method
+         return false;
+      }
+      // we handle rest of the methods
+      return true;
+   }
+
+   /**
+    * Returns true if the {@link Method} <code>m</code> is a public method.
+    * Else returns false
+    * 
+    * @param m The method
+    * @return
+    */
+   private boolean isPublic(Method m)
+   {
+      int modifiers = m.getModifiers();
+      if ((Modifier.PUBLIC & modifiers) == Modifier.PUBLIC)
+      {
+         return true;
+      }
+      return false;
+   }
+
+   /**
+    * Returns true if the {@link Method} <code>m</code> is a final method.
+    * Else returns false
+    * 
+    * @param m The method
+    * @return
+    */
+   private boolean isFinal(Method m)
+   {
+      int modifiers = m.getModifiers();
+      if ((Modifier.FINAL & modifiers) == Modifier.FINAL)
+      {
+         return true;
+      }
+      return false;
+   }
+
+   /**
+    * Returns true if the {@link Method} <code>m</code> is a static method.
+    * Else returns false
+    * 
+    * @param m The method
+    * @return
+    */
+   private boolean isStatic(Method m)
+   {
+      int modifiers = m.getModifiers();
+      if ((Modifier.STATIC & modifiers) == Modifier.STATIC)
+      {
+         return true;
+      }
+      return false;
+   }
+
+   /**
+    * Returns true if the {@link Method} <code>m</code> is a native method.
+    * Else returns false
+    * 
+    * @param m The method
+    * @return
+    */
+   private boolean isNative(Method m)
+   {
+      int modifiers = m.getModifiers();
+      if ((Modifier.NATIVE & modifiers) == Modifier.NATIVE)
+      {
+         return true;
+      }
+      return false;
+   }
+}

Modified: projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java	2010-02-15 15:14:10 UTC (rev 100970)
+++ projects/ejb3/components/nointerface/trunk/impl/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -21,28 +21,21 @@
  */
 package org.jboss.ejb3.nointerface.impl.view.factory;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Set;
 
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
-import javassist.Modifier;
+import javassist.util.proxy.ProxyFactory;
+import javassist.util.proxy.ProxyFactory.ClassLoaderProvider;
 
+import org.jboss.ejb3.nointerface.impl.view.JavassistInvocationHandlerAdapter;
+import org.jboss.ejb3.nointerface.impl.view.NoInterfaceViewMethodFilter;
 import org.jboss.ejb3.nointerface.spi.view.factory.NoInterfaceViewFactory;
 import org.jboss.logging.Logger;
 
 /**
- * NoInterfaceEJBViewFactoryBase
+ * {@link JavassistNoInterfaceViewFactory} uses Javassist to create
+ * nointerface view proxies for a EJB which exposes the nointerface view
  *
- * Creates a no-interface view for a EJB as per the EJB3.1 spec (section 3.4.4)
- *
+ * 
  * @see NoInterfaceViewFactory
  * @author Jaikiran Pai
  * @version $Revision: $
@@ -51,17 +44,6 @@
 {
 
    /**
-    * The proxies (sub-classes) created for the bean class need to be
-    * unique. This unique number is appended to the generated class name
-    */
-   private static long nextUniqueNumberForNoViewInterfaceClassName = 0;
-
-   /**
-    * Used while generating unique number for the proxy class
-    */
-   private static Object nextUniqueNumberLock = new Object();
-
-   /**
     * Logger
     */
    private static Logger logger = Logger.getLogger(JavassistNoInterfaceViewFactory.class);
@@ -85,201 +67,52 @@
          logger.trace("Creating nointerface view for beanClass: " + beanClass + " with container " + invocationHandler);
       }
 
-      // Create a ClassPool and add the classpath using the classloader of the beanClass, so 
-      // that it uses the correct jar while looking up the class
-      ClassPool pool = new ClassPool();
-      pool.appendClassPath(new LoaderClassPath(beanClass.getClassLoader()));
-      
-      CtClass beanCtClass = pool.get(beanClass.getName());
+      ProxyFactory javassistProxyFactory = new ProxyFactory();
+      // set the classloader provider on the factory so that it uses the bean class' classloader
+      // during proxy creation
+      ProxyFactory.classLoaderProvider = new NoInterfaceViewProxyFactoryClassLoaderProvider();
 
-      // Create a sub-class (proxy) for the bean class. A unique name will be used for the subclass
-      CtClass proxyCtClass = pool.makeClass(beanClass.getName() + "_NoInterfaceProxy$" + getNextUniqueNumber(),
-            beanCtClass);
+      // set the bean class for which we need a proxy
+      javassistProxyFactory.setSuperclass(beanClass);
+      // set a method filter so that we can filter out invocations on methods
+      // which are *not* to be handled by a nointerface view 
+      javassistProxyFactory.setFilter(new NoInterfaceViewMethodFilter());
+      // Set our method handler which is responsible for handling the method invocations
+      // on the proxy
+      javassistProxyFactory.setHandler(new JavassistInvocationHandlerAdapter(invocationHandler));
 
-      // We need to maintain a reference of the invocationHandler in the proxy, so that we can
-      // forward the method calls to invocationHandler.invoke. Create a new field in the sub-class (proxy)
-      CtField invocationHandlerField = CtField.make("private java.lang.reflect.InvocationHandler invocationHandler;",
-            proxyCtClass);
-      proxyCtClass.addField(invocationHandlerField);
+      // create the proxy
+      Object proxy = javassistProxyFactory.create(new Class[0], new Object[0]);
+      // cast to the bean type and return
+      return beanClass.cast(proxy);
 
-      // get all public methods from the bean class
-      Set<CtMethod> beanPublicMethods = getAllPublicNonStaticNonFinalMethods(beanCtClass);
-
-      // Override each of the public methods
-      for (CtMethod beanPublicMethod : beanPublicMethods)
-      {
-         // Methods from java.lang.Object can be skipped, if they are
-         // not implemented (overriden) in the bean class. TODO: Do we really need to do this?
-         if (shouldMethodBeSkipped(pool, beanPublicMethod))
-         {
-            logger.debug("Skipping " + beanPublicMethod.getName() + " on bean " + beanCtClass.getName()
-                  + " from no-interface view");
-            continue;
-         }
-         // We should not be changing the bean class methods. So we need to create a copy of the methods
-         // for the sub-class (proxy)
-         CtMethod proxyPublicMethod = CtNewMethod.copy(beanPublicMethod, proxyCtClass, null);
-         // All the public methods of the bean should now be overriden (through the proxy)
-         // to give a call to the container.invoke
-         // Ex: If the bean's public method was:
-         // public String sayHi(String name) { return "Hi " + name; }
-         // then it will be changed in the proxy to
-         // public String sayHi(String name) { java.lang.reflect.Method currentMethod = beanClass.getName() + ".class.getMethod(theMethodName,params);
-         // return container.invoke(this,currentMethod,args); }
-         proxyPublicMethod = overridePublicMethod(invocationHandler, beanClass, beanPublicMethod, proxyPublicMethod);
-         // We have now created the overriden method. We need to add it to the proxy
-         proxyCtClass.addMethod(proxyPublicMethod);
-         if (logger.isTraceEnabled())
-         {
-            logger.trace("Added overriden implementation for method " + proxyPublicMethod.getName()
-                  + " in no-interface view " + proxyCtClass.getName() + " for bean " + beanClass.getName());
-         }
-      }
-      // Add java.io.Serializable as the interface for the proxy (since it goes into JNDI)
-      //proxyCtClass.addInterface(pool.get(Serializable.class.getName()));
-      proxyCtClass.addMethod(createEqualsMethod(pool, proxyCtClass));
-
-      // We are almost done (except for setting the container field in the proxy)
-      // Let's first create a java.lang.Class (i.e. load) out of the javassist class
-      // using the classloader of the bean
-      Class<?> proxyClass = proxyCtClass.toClass(beanClass.getClassLoader(), beanClass.getProtectionDomain());
-      // time to set the container field through normal java reflection
-      Object proxyInstance = proxyClass.newInstance();
-      Field containerInProxy = proxyClass.getDeclaredField("invocationHandler");
-      containerInProxy.setAccessible(true);
-      containerInProxy.set(proxyInstance, invocationHandler);
-
-      // return the proxy instance
-      return beanClass.cast(proxyInstance);
-
    }
 
-   private <T> CtMethod overridePublicMethod(InvocationHandler container, Class<T> beanClass,
-         CtMethod publicMethodOnBean, CtMethod publicMethodOnProxy) throws Exception
-   {
-      publicMethodOnProxy.setBody("{"
-            +
-            // The proxy needs to call the container.invoke
-            // the InvocationHandler.invoke accepts (Object proxy,Method method,Object[] args)
-            // This view needs to create a java.lang.reflect.Method object based on the "current method"
-            // that is invoked on the view. Note that we need to get the Method from the beanclass.
-            // Note: All the '$' parameters used are javassist specific syntax
-            "java.lang.reflect.Method currentMethod = " + beanClass.getName() + ".class.getMethod(\""
-            + publicMethodOnBean.getName() + "\",$sig);" +
-            // At this point we have the container, the Method to be invoked and the parameters to be passed
-            // All we have to do is invoke the container
-            "return ($r) invocationHandler.invoke(this,currentMethod,$args);" + "}");
-
-      return publicMethodOnProxy;
-   }
-
    /**
-    * Returns all public, non-static and non-final methods for the class
+    * {@link NoInterfaceViewProxyFactoryClassLoaderProvider} is responsible for returning
+    * the correct classloader for nointerface view proxy creation through
+    * the javassist {@link ProxyFactory}
     *
-    * @param ctClass The class whose non-final, non-static public methods are to be returned
-    * @return
-    * @throws Exception
+    * @author Jaikiran Pai
+    * @version $Revision: $
     */
-   private Set<CtMethod> getAllPublicNonStaticNonFinalMethods(CtClass ctClass) throws Exception
+   private class NoInterfaceViewProxyFactoryClassLoaderProvider implements ClassLoaderProvider
    {
-      CtMethod[] allMethods = ctClass.getMethods();
-      Set<CtMethod> publicMethods = new HashSet<CtMethod>();
 
-      for (CtMethod ctMethod : allMethods)
+      /**
+       * Returns the {@link ClassLoader} for creating the nointerface view proxy.
+       * <p>
+       *   Internally, returns the {@link ClassLoader} which loaded {@link ProxyFactory#getSuperclass()},
+       *   since the nointerface view is created by setting the bean class as the
+       *   "super class" through {@link ProxyFactory#setSuperclass(Class)}
+       * </p> 
+       * @see javassist.util.proxy.ProxyFactory.ClassLoaderProvider#get(javassist.util.proxy.ProxyFactory)
+       */
+      @Override
+      public ClassLoader get(ProxyFactory pf)
       {
-         int modifier = ctMethod.getModifiers();
-         // Public non-static non-final methods
-         if (((Modifier.PUBLIC & modifier) == Modifier.PUBLIC) && ((Modifier.STATIC & modifier) != Modifier.STATIC)
-               && ((Modifier.FINAL & modifier) != Modifier.FINAL) && ((Modifier.NATIVE & modifier) != Modifier.NATIVE))
-         {
-            publicMethods.add(ctMethod);
-         }
+         return pf.getSuperclass().getClassLoader();
       }
-      return publicMethods;
-   }
 
-   /**
-    * Checks whether a method has to be skipped from being overriden in the proxy
-    * that is returned for the no-interface view.
-    *
-    * TODO: Do we really need this. Need to think more. Let's keep it for the time-being
-    *
-    * @param beanCtClass
-    * @param ctMethod
-    * @return
-    * @throws Exception
-    */
-   private boolean shouldMethodBeSkipped(CtClass beanCtClass, CtMethod ctMethod) throws Exception
-   {
-
-      //      List<CtMethod> declaredMethods = Arrays.asList(beanCtClass.getDeclaredMethods());
-      //      if (declaredMethods.contains(ctMethod))
-      //      {
-      //         return false;
-      //      }
-      //      CtClass objectCtClass = ClassPool.getDefault().get(Object.class.getName());
-      //      CtMethod[] methodsInObjectClass = objectCtClass.getMethods();
-      //      List<CtMethod> methodsToBeSkipped = Arrays.asList(methodsInObjectClass);
-      //      return methodsToBeSkipped.contains(ctMethod);
-      return false;
-
    }
-
-   private static boolean shouldMethodBeSkipped(ClassPool pool, CtMethod ctMethod) throws Exception
-   {
-      CtClass paramsToEqualsMethodInObjectClass[] = new CtClass[]
-      {pool.get(Object.class.getName())};
-      if (!ctMethod.getName().equals("equals"))
-      {
-         return false;
-      }
-      if (ctMethod.getParameterTypes().length != paramsToEqualsMethodInObjectClass.length)
-      {
-         return false;
-      }
-      CtClass paramsToEqualsMethodInOtherClass[] = ctMethod.getParameterTypes();
-      return paramsToEqualsMethodInObjectClass[0].equals(paramsToEqualsMethodInOtherClass[0]);
-
-   }
-
-   private static CtMethod createEqualsMethod(ClassPool pool, CtClass proxyCtClass) throws Exception
-   {
-      String body = "{" + "java.lang.reflect.Method currentMethod = " + Object.class.getName()
-            + ".class.getMethod(\"equals\",$sig);" + "return ($r) invocationHandler.invoke(this,currentMethod,$args);"
-            + "}";
-
-      Method equals = Object.class.getMethod("equals", new Class<?>[]
-      {Object.class});
-      CtClass returnType = pool.get(equals.getReturnType().getName());
-      CtClass paramTypes[] = new CtClass[equals.getParameterTypes().length];
-      int i = 0;
-      for (Class<?> paramType : equals.getParameterTypes())
-      {
-         paramTypes[i++] = pool.get(paramType.getName());
-      }
-
-      CtClass exceptionTypes[] = new CtClass[equals.getExceptionTypes().length];
-      int j = 0;
-      for (Class<?> exceptionType : equals.getExceptionTypes())
-      {
-         exceptionTypes[j++] = pool.get(exceptionType.getName());
-      }
-
-      return CtNewMethod.make(returnType, equals.getName(), paramTypes, exceptionTypes, body, proxyCtClass);
-   }
-
-   /**
-    * Get the next unique number which will be used for the proxy class name
-    *
-    * @return
-    */
-   private long getNextUniqueNumber()
-   {
-      synchronized (nextUniqueNumberLock)
-      {
-         this.nextUniqueNumberForNoViewInterfaceClassName++;
-         return this.nextUniqueNumberForNoViewInterfaceClassName;
-      }
-   }
-
 }

Added: projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/Contact.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/Contact.java	                        (rev 0)
+++ projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/Contact.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -0,0 +1,56 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.integration.test.ejbthree2014;
+
+/**
+ * Contact
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class Contact
+{
+
+   private String name;
+
+   private String alias;
+   
+   public Contact(String name)
+   {
+      this.name = name;
+   }
+
+   public String getName()
+   {
+      return this.name;
+   }
+   
+   public void setAlias(String alias)
+   {
+      this.alias = alias;
+   }
+   
+   public String getAlias()
+   {
+      return this.alias;
+   }
+}

Added: projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactBean.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactBean.java	                        (rev 0)
+++ projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactBean.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -0,0 +1,41 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.integration.test.ejbthree2014;
+
+import javax.ejb.Stateless;
+
+/**
+ * ContactBean
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+ at Stateless
+public class ContactBean
+{
+
+   public Contact createAlias(Contact contact)
+   {
+      contact.setAlias(contact.getName() + "-alias");
+      return contact;
+   }
+}

Added: projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactManager.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactManager.java	                        (rev 0)
+++ projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/ContactManager.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -0,0 +1,33 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.integration.test.ejbthree2014;
+
+/**
+ * ContactManager
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public interface ContactManager
+{
+   String getContactAlias(String contactName);
+}

Added: projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/WrapperBean.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/WrapperBean.java	                        (rev 0)
+++ projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/WrapperBean.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -0,0 +1,53 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.integration.test.ejbthree2014;
+
+import javax.ejb.EJB;
+import javax.ejb.Remote;
+import javax.ejb.Stateless;
+
+import org.jboss.ejb3.annotation.RemoteBinding;
+
+/**
+ * WrapperBean
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+ at Stateless
+ at Remote(ContactManager.class)
+ at RemoteBinding (jndiBinding = WrapperBean.JNDI_NAME)
+public class WrapperBean implements ContactManager
+{
+
+   public static final String JNDI_NAME = "RemoteWrapperBean";
+
+   @EJB
+   private ContactBean contactBean;
+
+   public String getContactAlias(String contactName)
+   {
+      Contact contact = new Contact(contactName);
+      contact = this.contactBean.createAlias(contact);
+      return contact.getAlias();
+   }
+}

Added: projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/unit/ClassLoadingUnitTestCase.java
===================================================================
--- projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/unit/ClassLoadingUnitTestCase.java	                        (rev 0)
+++ projects/ejb3/components/nointerface/trunk/testsuite/src/test/java/org/jboss/ejb3/nointerface/integration/test/ejbthree2014/unit/ClassLoadingUnitTestCase.java	2010-02-15 15:34:31 UTC (rev 100971)
@@ -0,0 +1,101 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.integration.test.ejbthree2014.unit;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import junit.framework.Assert;
+
+import org.jboss.ejb3.nointerface.integration.test.AbstractNoInterfaceTestCase;
+import org.jboss.ejb3.nointerface.integration.test.ejbthree2014.ContactManager;
+import org.jboss.ejb3.nointerface.integration.test.ejbthree2014.WrapperBean;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the fix for https://jira.jboss.org/jira/browse/EJBTHREE-2014
+ * 
+ * <p>
+ *  Loading of custom class objects being passed through methods of a nointerface view
+ *  bean were not being handled correctly, which was resulting in a {@link ClassNotFoundException}.
+ *       
+ * </p>
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class ClassLoadingUnitTestCase extends AbstractNoInterfaceTestCase
+{
+
+   
+
+   private URL deployment;
+
+   private final String JAR_NAME = "classloading-test.jar";
+
+   /**
+    * 
+    * @return
+    * @throws Exception
+    */
+   @Before
+   public void before() throws Exception
+   {
+      File jar = buildSimpleJar(JAR_NAME, WrapperBean.class.getPackage());
+      this.deployment = jar.toURI().toURL();
+      this.redeploy(deployment);
+
+   }
+
+   @After
+   public void after() throws Exception
+   {
+      if (this.deployment != null)
+      {
+         this.undeploy(deployment);
+      }
+   }
+
+   /**
+    * Test that a nointerface view bean which accepts a custom class object (i.e. not classes not 
+    * belonging to the rt.jar) is able to process invocations successfully.
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testInvocationWithCustomClassMethodParam() throws Exception
+   {
+      Context ctx = new InitialContext();
+      ContactManager contactManager = (ContactManager) ctx.lookup(WrapperBean.JNDI_NAME);
+      String contactname = "somename";
+      String alias = contactManager.getContactAlias(contactname);
+
+      Assert.assertNotNull("Alias returned for contact name " + contactname + " is null", alias);
+      Assert.assertEquals("Unexpected alias returned", contactname + "-alias", alias);
+
+   }
+}




More information about the jboss-cvs-commits mailing list