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 <[email protected]> wrote:
> Hi andreas,
> On Thu, Oct 13, 2011 at 12:26 AM, Andreas Veithen <
> [email protected]> 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 <[email protected]> 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 - [email protected]
>> > mobile - 071 56 91 321
>> >
>> >
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [email protected]
>> For additional commands, e-mail: [email protected]
>>
>>
>
>
> --
> Supun Malinga,
>
> Software Engineer,
> WSO2 Inc.
> http://wso2.com
> http://wso2.org
> email - [email protected] <[email protected]>
> mobile - 071 56 91 321
>
>
--
Supun Malinga,
Software Engineer,
WSO2 Inc.
http://wso2.com
http://wso2.org
email - [email protected] <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]