Hi All, After some work I could modify the ejb Message receivers to support ejb3.0. I made this as a separate message receiver. Three new classes introduced. org/apache/axis2/rpc/receivers/ejb/EJB3Util.java org/apache/axis2/rpc/receivers/ejb/EJB3InOnlyMessageReceiver.jav org/apache/axis2/rpc/receivers/ejb/EJB3MessageReceiver.java
Created a jira @ [1]. Attached a draft patch to the jira. I'll further look into do more fine tuning and testing with different appservers. [1] https://issues.apache.org/jira/browse/AXIS2-5204 thanks, On Thu, Oct 13, 2011 at 12:05 PM, Supun Malinga <sup...@wso2.com> wrote: > Hi andreas, > On Thu, Oct 13, 2011 at 12:26 AM, Andreas Veithen < > andreas.veit...@gmail.com> wrote: > >> Some quick comments: >> >> * There have been lots of changes in EJB3, but AFAIK the only ones >> relevant for Axis2 are those regarding the client view of a stateless >> session bean. The only major change in that area is the removal of the >> home interface. To cope with that you probably don't need to drop the >> support for EJB2. >> > > Agreed. will focus on sumedha's idea as well. > > >> * People who use EJB3 embrace the J2EE specs and are likely to use the >> Web service client view (i.e. the JAX-WS support provided by the >> container) to expose their beans as Web Services. That is also much >> more powerful than the RPC stuff in Axis2. Therefore it is actually >> not unlikely that there are more people interested in EJB2 support (to >> expose their legacy beans as Web services) than in EJB3 support. >> > > AFAIU jax-ws support is only provided for stateless session beans. Also > there are lots of ejb2 to ejb3 conversion tools available. > > thanks and regards, > >> >> Andreas >> >> On Wed, Oct 12, 2011 at 03:03, Supun Malinga <sup...@wso2.com> wrote: >> > Hi folks, >> > axis2 supports exposing ejb2 components as web-services. Refer [1]. >> This is >> > handles via extending Message receiver to look-up jndi contexts and >> handle >> > invocations. >> > For eg: org.apache.axis2.rpc.receivers.ejb.EJBInOnlyMessageReceiver >> > org.apache.axis2.rpc.receivers.ejb.EJBMessageReceiver >> > Currently this implementation works with ejb 2.0. >> > Since ejb 3.x has changed lot(from architectural level) since ejb2 this >> > implementation is not usable with ejb 3. I'm working on improving it to >> > support ejb 3.0. >> > But we may have to move away from support for ejb2 while doing this. As >> ejb >> > 2 is a pretty old standard [2] and ejb 3 is widely used. >> > I'am still working to come up with a implementation for this. >> > Ideas, comments are much appreciated. >> > [1] http://axis.apache.org/axis2/java/core/docs/ejb-provider.html >> > [2] http://en.wikipedia.org/wiki/Enterprise_JavaBean#Version_history >> > >> > thanks, >> > -- >> > Supun Malinga, >> > >> > Software Engineer, >> > WSO2 Inc. >> > http://wso2.com >> > http://wso2.org >> > email - sup...@wso2.com >> > mobile - 071 56 91 321 >> > >> > >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: java-dev-unsubscr...@axis.apache.org >> For additional commands, e-mail: java-dev-h...@axis.apache.org >> >> > > > -- > Supun Malinga, > > Software Engineer, > WSO2 Inc. > http://wso2.com > http://wso2.org > email - sup...@wso2.com <sup...@wso2.com> > mobile - 071 56 91 321 > > -- Supun Malinga, Software Engineer, WSO2 Inc. http://wso2.com http://wso2.org email - sup...@wso2.com <sup...@wso2.com> mobile - 071 56 91 321
Index: modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3Util.java =================================================================== --- modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3Util.java (revision 116208) +++ modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3Util.java (working copy) @@ -28,35 +28,27 @@ import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; -import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Properties; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; -public class EJBUtil { - public static final java.lang.String EJB_JNDI_NAME = "beanJndiName"; - public static final java.lang.String EJB_HOME_INTERFACE_NAME = "homeInterfaceName"; - public static final java.lang.String EJB_REMOTE_INTERFACE_NAME = "remoteInterfaceName"; - public static final java.lang.String EJB_LOCAL_HOME_INTERFACE_NAME = "localHomeInterfaceName"; - public static final java.lang.String EJB_LOCAL_INTERFACE_NAME = "localInterfaceName"; - public static final java.lang.String EJB_INITIAL_CONTEXT_FACTORY = "jndiContextClass"; - public static final java.lang.String EJB_PROVIDER_URL = "providerUrl"; - public static final java.lang.String EJB_JNDI_USERNAME = "jndiUser"; - public static final java.lang.String EJB_JNDI_PASSWORD = "jndiPassword"; +public class EJB3Util { + public static final String EJB_JNDI_NAME = "beanJndiName"; + public static final String EJB_REMOTE_INTERFACE_NAME = "remoteInterfaceName"; + public static final String EJB_LOCAL_INTERFACE_NAME = "localInterfaceName"; + public static final String EJB_INITIAL_CONTEXT_FACTORY = "jndiContextClass"; + public static final String EJB_PROVIDER_URL = "providerUrl"; + public static final String EJB_JNDI_USERNAME = "jndiUser"; + public static final String EJB_JNDI_PASSWORD = "jndiPassword"; private static ExecutorService workerPool = null; static { workerPool = - new ThreadPoolExecutor(1, 50, 150L, TimeUnit.SECONDS, new LinkedBlockingQueue(), - new DefaultThreadFactory( - new ThreadGroup("EJB provider thread group"), - "EJBProvider")); + new ThreadPoolExecutor(1, 50, 150L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), + new DefaultThreadFactory( + new ThreadGroup("EJB provider thread group"), "EJBProvider")); } /** @@ -64,7 +56,7 @@ * * @param msgContext the message context * @return an object that implements the service - * @throws AxisFault if fails + * @throws org.apache.axis2.AxisFault if fails */ protected static Object makeNewServiceObject(MessageContext msgContext) throws AxisFault { CountDownLatch startLatch = new CountDownLatch(1); @@ -88,10 +80,11 @@ private static class EJBClientWorker implements Runnable { private MessageContext msgContext = null; + private CountDownLatch startLatch = null; private CountDownLatch stopLatch = null; - protected static final Class[] empty_class_array = new Class[0]; - protected static final Object[] empty_object_array = new Object[0]; + // protected static final Class[] empty_class_array = new Class[0]; +// protected static final Object[] empty_object_array = new Object[0]; private static InitialContext cached_context = null; private Exception exception = null; private Object returnedValue = null; @@ -116,26 +109,28 @@ } } ); - Parameter remoteHomeName = service.getParameter(EJB_HOME_INTERFACE_NAME); - Parameter localHomeName = service.getParameter(EJB_LOCAL_HOME_INTERFACE_NAME); + Parameter remoteName = service.getParameter(EJB_REMOTE_INTERFACE_NAME); + Parameter localName = service.getParameter(EJB_LOCAL_INTERFACE_NAME); Parameter jndiName = service.getParameter(EJB_JNDI_NAME); - Parameter homeName = (remoteHomeName != null ? remoteHomeName : localHomeName); + Parameter interfaceName = (remoteName != null ? remoteName : localName); if (jndiName == null || jndiName.getValue() == null) { throw new AxisFault("jndi name is not specified"); - } else if (homeName == null || homeName.getValue() == null) { - // cannot find both remote home and local home + } else if (interfaceName == null || interfaceName.getValue() == null) { + // cannot find both ejb remote and local interfaces + //todo - in ejb 3.1 this is also not required! throw new AxisFault("ejb remote/local home class name is not specified"); } // we create either the ejb using either the RemoteHome or LocalHome object - if (remoteHomeName != null) + if (remoteName != null) { returnedValue = createRemoteEJB(msgContext, - ((String)jndiName.getValue()).trim(), - ((String)homeName.getValue()).trim()); - else - returnedValue = createLocalEJB(msgContext, ((String)jndiName.getValue()).trim(), - ((String)homeName.getValue()).trim()); + ((String) jndiName.getValue()).trim(), + ((String) interfaceName.getValue()).trim()); + } else { + returnedValue = createLocalEJB(msgContext, ((String) jndiName.getValue()).trim(), + ((String) interfaceName.getValue()).trim()); + } } catch (Exception e) { e.printStackTrace(); exception = e; @@ -145,73 +140,52 @@ } /** - * Create an EJB using a remote home object + * Create an EJB using a ejb remote object * - * @param msgContext the message context - * @param beanJndiName The JNDI name of the EJB remote home class - * @param homeName the name of the home interface class + * @param msgContext the message context + * @param beanJndiName The JNDI name of the EJB remote class + * @param interfaceName the name of the interface class * @return an EJB * @throws Exception If fails */ private Object createRemoteEJB(MessageContext msgContext, String beanJndiName, - String homeName) throws Exception { - // Get the EJB Home object from JNDI - Object ejbHome = getEJBHome(msgContext.getAxisService(), beanJndiName); - Class cls = getContextClassLoader().loadClass(homeName); - Object ehome = javax.rmi.PortableRemoteObject.narrow(ejbHome, cls); - - // Invoke the create method of the ejbHome class without actually - // touching any EJB classes (i.e. no cast to EJBHome) - Method createMethod = cls.getMethod("create", empty_class_array); - - return createMethod.invoke(ehome, empty_object_array); + String interfaceName) throws Exception { + Class cls = getContextClassLoader().loadClass(interfaceName); + // Get the EJB Remote object from JNDI + Object ejbRemote = getEJBInterface(msgContext.getAxisService(), beanJndiName); + return cls.cast(ejbRemote); } /** * Create an EJB using a local home object * - * @param msgContext the message context - * @param beanJndiName The JNDI name of the EJB local home class - * @param homeName the name of the home interface class + * @param msgContext the message context + * @param beanJndiName The JNDI name of the EJB local interface class + * @param interfaceName the name of the local interface class * @return an EJB * @throws Exception if fails */ private Object createLocalEJB(MessageContext msgContext, String beanJndiName, - String homeName) + String interfaceName) throws Exception { - // Get the EJB Home object from JNDI - Object ejbHome = getEJBHome(msgContext.getAxisService(), beanJndiName); - - // the home object is a local home object - Object ehome; - - Class cls = getContextClassLoader().loadClass(homeName); - - if (cls.isInstance(ejbHome)) - ehome = ejbHome; - else { - throw new ClassCastException("bad ejb home type"); - } - - // Invoke the create method of the ejbHome class without actually - // touching any EJB classes (i.e. no cast to EJBLocalHome) - Method createMethod = cls.getMethod("create", empty_class_array); - - return createMethod.invoke(ehome, empty_object_array); + Class cls = getContextClassLoader().loadClass(interfaceName); + // Get the EJB local interface object from JNDI + Object ejbLocal = getEJBInterface(msgContext.getAxisService(), beanJndiName); + return cls.cast(ejbLocal); } /** - * Common routine to do the JNDI lookup on the Home interface object username and password + * Common routine to do the JNDI lookup on the remote/local interface object username and password * for jndi lookup are got from the configuration or from the messageContext if not found in * the configuration * * @param service AxisService object - * @param beanJndiName JNDI name of the EJB home object - * @return EJB home object - * @throws AxisFault If fals + * @param beanJndiName JNDI name of the EJB remote/local object + * @return EJB remote/local object + * @throws org.apache.axis2.AxisFault If fails */ - private Object getEJBHome(AxisService service, String beanJndiName) throws AxisFault { - Object ejbHome = null; + private Object getEJBInterface(AxisService service, String beanJndiName) throws AxisFault { + Object ejbRemote = null; // Set up an InitialContext and use it get the beanJndiName from JNDI try { @@ -226,7 +200,7 @@ if (properties == null) properties = new Properties(); properties.setProperty(Context.SECURITY_PRINCIPAL, - ((String)username.getValue()).trim()); + ((String) username.getValue()).trim()); } // password @@ -235,7 +209,7 @@ if (properties == null) properties = new Properties(); properties.setProperty(Context.SECURITY_CREDENTIALS, - ((String)password.getValue()).trim()); + ((String) password.getValue()).trim()); } // factory class @@ -244,7 +218,7 @@ if (properties == null) properties = new Properties(); properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, - ((String)factoryClass.getValue()).trim()); + ((String) factoryClass.getValue()).trim()); } // contextUrl @@ -253,7 +227,7 @@ if (properties == null) properties = new Properties(); properties.setProperty(Context.PROVIDER_URL, - ((String)contextUrl.getValue()).trim()); + ((String) contextUrl.getValue()).trim()); } // get context using these properties @@ -264,44 +238,41 @@ throw new AxisFault("cannot create initial context"); try { - ejbHome = getEJBHome(context, beanJndiName); + ejbRemote = lookUpEJBInterface(context, beanJndiName); } catch (Exception e) { - ejbHome = getEJBHome(context, beanJndiName); // Retry for the 2nd time to overcome issues related to cahing - } + ejbRemote = lookUpEJBInterface(context, beanJndiName); // Retry for the 2nd time to overcome issues related to cahing + } - if (ejbHome == null) + if (ejbRemote == null) throw new AxisFault("cannot find jndi home"); - } - catch (Exception exception) { + } catch (Exception exception) { throw AxisFault.makeFault(exception); } - return ejbHome; + return ejbRemote; } private InitialContext getCachedContext() - throws javax.naming.NamingException { + throws NamingException { if (cached_context == null) cached_context = new InitialContext(); return cached_context; } - private InitialContext getContext(Properties properties) - throws AxisFault, javax.naming.NamingException { - return ((properties == null) - ? getCachedContext() - : new InitialContext(properties)); + throws AxisFault, NamingException { + return ((properties == null) ? getCachedContext() : new InitialContext(properties)); } - private Object getEJBHome(InitialContext context, String beanJndiName) - throws AxisFault, javax.naming.NamingException { + + private Object lookUpEJBInterface(InitialContext context, String beanJndiName) + throws AxisFault, NamingException { return context.lookup(beanJndiName); } private ClassLoader getContextClassLoader() { - return (ClassLoader)AccessController.doPrivileged( + return (ClassLoader) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return Thread.currentThread().getContextClassLoader(); @@ -317,5 +288,6 @@ public Object getReturnedValue() { return returnedValue; } + } } Index: modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3InOnlyMessageReceiver.java =================================================================== --- modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3InOnlyMessageReceiver.java (revision 116208) +++ modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3InOnlyMessageReceiver.java (working copy) @@ -23,9 +23,9 @@ import org.apache.axis2.context.MessageContext; import org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver; -public class EJBInOnlyMessageReceiver extends RPCInOnlyMessageReceiver { +public class EJB3InOnlyMessageReceiver extends RPCInOnlyMessageReceiver { protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault { - return EJBUtil.makeNewServiceObject(msgContext); + return EJB3Util.makeNewServiceObject(msgContext); } } Index: modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3MessageReceiver.java =================================================================== --- modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3MessageReceiver.java (revision 0) +++ modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJB3MessageReceiver.java (revision 0) @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.axis2.rpc.receivers.ejb; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.rpc.receivers.RPCMessageReceiver; + +public class EJB3MessageReceiver extends RPCMessageReceiver { + + protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault { + return EJB3Util.makeNewServiceObject(msgContext); + } +}
--------------------------------------------------------------------- To unsubscribe, e-mail: java-dev-unsubscr...@axis.apache.org For additional commands, e-mail: java-dev-h...@axis.apache.org