You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2007/02/26 16:03:39 UTC

svn commit: r511842 - in /webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb: ./ EJBInOnlyMessageReceiver.java EJBInOutAsyncMessageReceiver.java EJBMessageReceiver.java EJBUtil.java

Author: dims
Date: Mon Feb 26 07:03:38 2007
New Revision: 511842

URL: http://svn.apache.org/viewvc?view=rev&rev=511842
Log:
Fix for AXIS2-1998 - EJB provider is not available for Axis2

Added:
    webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/
    webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOnlyMessageReceiver.java
    webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOutAsyncMessageReceiver.java
    webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBMessageReceiver.java
    webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBUtil.java

Added: webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOnlyMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOnlyMessageReceiver.java?view=auto&rev=511842
==============================================================================
--- webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOnlyMessageReceiver.java (added)
+++ webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOnlyMessageReceiver.java Mon Feb 26 07:03:38 2007
@@ -0,0 +1,54 @@
+package org.apache.axis2.rpc.receivers.ejb;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+public class EJBInOnlyMessageReceiver extends RPCInOnlyMessageReceiver {
+
+    protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        return EJBUtil.makeNewServiceObject(msgContext);
+    }
+}
+package org.apache.axis2.rpc.receivers.ejb;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+public class EJBInOnlyMessageReceiver extends RPCInOnlyMessageReceiver {
+
+    protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        return EJBUtil.makeNewServiceObject(msgContext);
+    }
+}

Added: webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOutAsyncMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOutAsyncMessageReceiver.java?view=auto&rev=511842
==============================================================================
--- webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOutAsyncMessageReceiver.java (added)
+++ webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBInOutAsyncMessageReceiver.java Mon Feb 26 07:03:38 2007
@@ -0,0 +1,54 @@
+package org.apache.axis2.rpc.receivers.ejb;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.rpc.receivers.RPCInOutAsyncMessageReceiver;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+public class EJBInOutAsyncMessageReceiver extends RPCInOutAsyncMessageReceiver {
+
+    protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        return EJBUtil.makeNewServiceObject(msgContext);
+    }
+}
+package org.apache.axis2.rpc.receivers.ejb;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.rpc.receivers.RPCInOutAsyncMessageReceiver;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+public class EJBInOutAsyncMessageReceiver extends RPCInOutAsyncMessageReceiver {
+
+    protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        return EJBUtil.makeNewServiceObject(msgContext);
+    }
+}

Added: webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBMessageReceiver.java?view=auto&rev=511842
==============================================================================
--- webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBMessageReceiver.java (added)
+++ webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBMessageReceiver.java Mon Feb 26 07:03:38 2007
@@ -0,0 +1,54 @@
+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;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+public class EJBMessageReceiver extends RPCMessageReceiver {
+
+    protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        return EJBUtil.makeNewServiceObject(msgContext);
+    }
+}
+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;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+public class EJBMessageReceiver extends RPCMessageReceiver {
+
+    protected Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        return EJBUtil.makeNewServiceObject(msgContext);
+    }
+}

Added: webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBUtil.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBUtil.java?view=auto&rev=511842
==============================================================================
--- webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBUtil.java (added)
+++ webservices/axis2/trunk/java/modules/adb/src/org/apache/axis2/rpc/receivers/ejb/EJBUtil.java Mon Feb 26 07:03:38 2007
@@ -0,0 +1,584 @@
+package org.apache.axis2.rpc.receivers.ejb;
+
+import edu.emory.mathcs.backport.java.util.concurrent.*;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.util.threadpool.DefaultThreadFactory;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.lang.reflect.Method;
+import java.util.Properties;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+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";
+
+    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"));
+    }
+
+    /**
+     * Return a object which implements the service.
+     *
+     * @param msgContext the message context
+     * @return an object that implements the service
+     * @throws AxisFault if fails
+     */
+    protected static Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        CountDownLatch startLatch = new CountDownLatch(1);
+        CountDownLatch stopLatch = new CountDownLatch(1);
+        EJBClientWorker worker = new EJBClientWorker(msgContext, startLatch, stopLatch);
+        workerPool.execute(worker);
+        startLatch.countDown();
+        try {
+            stopLatch.await();
+        } catch (InterruptedException e) {
+            throw AxisFault.makeFault(e);
+        }
+
+        if (worker.getException()!=null) {
+            throw AxisFault.makeFault(worker.getException());
+        }
+
+        return worker.getReturnedValue();
+    }
+
+    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];
+        private static InitialContext cached_context = null;
+        private Exception exception = null;
+        private Object returnedValue = null;
+
+        public EJBClientWorker(MessageContext msgContext, CountDownLatch startLatch, CountDownLatch stopLatch) {
+            this.msgContext = msgContext;
+            this.startLatch = startLatch;
+            this.stopLatch = stopLatch;
+        }
+
+        public void run() {
+            try {
+                startLatch.await();
+                final AxisService service = msgContext.getAxisService();
+                AccessController.doPrivileged(
+                        new PrivilegedAction() {
+                            public Object run() {
+                                Thread.currentThread().setContextClassLoader(service.getClassLoader());
+                                return null;
+                            }
+                        }
+                );
+                Parameter remoteHomeName = service.getParameter(EJB_HOME_INTERFACE_NAME);
+                Parameter localHomeName = service.getParameter(EJB_LOCAL_HOME_INTERFACE_NAME);
+                Parameter jndiName = service.getParameter(EJB_JNDI_NAME);
+                Parameter homeName = (remoteHomeName != null ? remoteHomeName:localHomeName);
+
+                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
+                    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)
+                    returnedValue = createRemoteEJB(msgContext, ((String) jndiName.getValue()).trim(), ((String) homeName.getValue()).trim());
+                else
+                    returnedValue = createLocalEJB(msgContext, ((String) jndiName.getValue()).trim(), ((String) homeName.getValue()).trim());
+            } catch (Exception e) {
+                e.printStackTrace();
+                exception = e;
+            } finally {
+                stopLatch.countDown();
+            }
+        }
+
+        /**
+         * Create an EJB using a remote home 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
+         * @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);
+        }
+
+        /**
+         * 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
+         * @return an EJB
+         * @throws Exception if fails
+         */
+        private Object createLocalEJB(MessageContext msgContext, String beanJndiName, String homeName)
+                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);
+        }
+
+        /**
+         * Common routine to do the JNDI lookup on the Home 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
+         */
+        private Object getEJBHome(AxisService service, String beanJndiName) throws AxisFault {
+            Object ejbHome;
+
+            // Set up an InitialContext and use it get the beanJndiName from JNDI
+            try {
+                Properties properties = null;
+
+                // collect all the properties we need to access JNDI:
+                // username, password, factoryclass, contextUrl
+
+                // username
+                Parameter username = service.getParameter(EJB_JNDI_USERNAME);
+                if (username != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.SECURITY_PRINCIPAL, ((String) username.getValue()).trim());
+                }
+
+                // password
+                Parameter password = service.getParameter(EJB_JNDI_PASSWORD);
+                if (password != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.SECURITY_CREDENTIALS, ((String) password.getValue()).trim());
+                }
+
+                // factory class
+                Parameter factoryClass = service.getParameter(EJB_INITIAL_CONTEXT_FACTORY);
+                if (factoryClass != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, ((String) factoryClass.getValue()).trim());
+                }
+
+                // contextUrl
+                Parameter contextUrl = service.getParameter(EJB_PROVIDER_URL);
+                if (contextUrl != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.PROVIDER_URL, ((String) contextUrl.getValue()).trim());
+                }
+
+                // get context using these properties
+                InitialContext context = getContext(properties);
+
+                // if we didn't get a context, fail
+                if (context == null)
+                    throw new AxisFault("cannot create initial context");
+
+                ejbHome = getEJBHome(context, beanJndiName);
+
+                if (ejbHome == null)
+                    throw new AxisFault("cannot find jndi home");
+            }
+            catch (Exception exception) {
+                throw AxisFault.makeFault(exception);
+            }
+
+            return ejbHome;
+        }
+
+        private InitialContext getCachedContext()
+                throws javax.naming.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));
+        }
+
+        private Object getEJBHome(InitialContext context, String beanJndiName)
+                throws AxisFault, javax.naming.NamingException {
+            return context.lookup(beanJndiName);
+        }
+
+        private ClassLoader getContextClassLoader() {
+            return (ClassLoader) AccessController.doPrivileged(
+                    new PrivilegedAction() {
+                        public Object run() {
+                            return Thread.currentThread().getContextClassLoader();
+                        }
+                    }
+            );
+        }
+
+        public Exception getException() {
+            return exception;
+        }
+
+        public Object getReturnedValue() {
+            return returnedValue;
+        }
+    }
+}
+package org.apache.axis2.rpc.receivers.ejb;
+
+import edu.emory.mathcs.backport.java.util.concurrent.*;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.util.threadpool.DefaultThreadFactory;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.lang.reflect.Method;
+import java.util.Properties;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.
+*/
+
+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";
+
+    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"));
+    }
+
+    /**
+     * Return a object which implements the service.
+     *
+     * @param msgContext the message context
+     * @return an object that implements the service
+     * @throws AxisFault if fails
+     */
+    protected static Object makeNewServiceObject(MessageContext msgContext) throws AxisFault {
+        CountDownLatch startLatch = new CountDownLatch(1);
+        CountDownLatch stopLatch = new CountDownLatch(1);
+        EJBClientWorker worker = new EJBClientWorker(msgContext, startLatch, stopLatch);
+        workerPool.execute(worker);
+        startLatch.countDown();
+        try {
+            stopLatch.await();
+        } catch (InterruptedException e) {
+            throw AxisFault.makeFault(e);
+        }
+
+        if (worker.getException()!=null) {
+            throw AxisFault.makeFault(worker.getException());
+        }
+
+        return worker.getReturnedValue();
+    }
+
+    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];
+        private static InitialContext cached_context = null;
+        private Exception exception = null;
+        private Object returnedValue = null;
+
+        public EJBClientWorker(MessageContext msgContext, CountDownLatch startLatch, CountDownLatch stopLatch) {
+            this.msgContext = msgContext;
+            this.startLatch = startLatch;
+            this.stopLatch = stopLatch;
+        }
+
+        public void run() {
+            try {
+                startLatch.await();
+                final AxisService service = msgContext.getAxisService();
+                AccessController.doPrivileged(
+                        new PrivilegedAction() {
+                            public Object run() {
+                                Thread.currentThread().setContextClassLoader(service.getClassLoader());
+                                return null;
+                            }
+                        }
+                );
+                Parameter remoteHomeName = service.getParameter(EJB_HOME_INTERFACE_NAME);
+                Parameter localHomeName = service.getParameter(EJB_LOCAL_HOME_INTERFACE_NAME);
+                Parameter jndiName = service.getParameter(EJB_JNDI_NAME);
+                Parameter homeName = (remoteHomeName != null ? remoteHomeName:localHomeName);
+
+                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
+                    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)
+                    returnedValue = createRemoteEJB(msgContext, ((String) jndiName.getValue()).trim(), ((String) homeName.getValue()).trim());
+                else
+                    returnedValue = createLocalEJB(msgContext, ((String) jndiName.getValue()).trim(), ((String) homeName.getValue()).trim());
+            } catch (Exception e) {
+                e.printStackTrace();
+                exception = e;
+            } finally {
+                stopLatch.countDown();
+            }
+        }
+
+        /**
+         * Create an EJB using a remote home 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
+         * @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);
+        }
+
+        /**
+         * 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
+         * @return an EJB
+         * @throws Exception if fails
+         */
+        private Object createLocalEJB(MessageContext msgContext, String beanJndiName, String homeName)
+                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);
+        }
+
+        /**
+         * Common routine to do the JNDI lookup on the Home 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
+         */
+        private Object getEJBHome(AxisService service, String beanJndiName) throws AxisFault {
+            Object ejbHome;
+
+            // Set up an InitialContext and use it get the beanJndiName from JNDI
+            try {
+                Properties properties = null;
+
+                // collect all the properties we need to access JNDI:
+                // username, password, factoryclass, contextUrl
+
+                // username
+                Parameter username = service.getParameter(EJB_JNDI_USERNAME);
+                if (username != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.SECURITY_PRINCIPAL, ((String) username.getValue()).trim());
+                }
+
+                // password
+                Parameter password = service.getParameter(EJB_JNDI_PASSWORD);
+                if (password != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.SECURITY_CREDENTIALS, ((String) password.getValue()).trim());
+                }
+
+                // factory class
+                Parameter factoryClass = service.getParameter(EJB_INITIAL_CONTEXT_FACTORY);
+                if (factoryClass != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, ((String) factoryClass.getValue()).trim());
+                }
+
+                // contextUrl
+                Parameter contextUrl = service.getParameter(EJB_PROVIDER_URL);
+                if (contextUrl != null) {
+                    if (properties == null)
+                        properties = new Properties();
+                    properties.setProperty(Context.PROVIDER_URL, ((String) contextUrl.getValue()).trim());
+                }
+
+                // get context using these properties
+                InitialContext context = getContext(properties);
+
+                // if we didn't get a context, fail
+                if (context == null)
+                    throw new AxisFault("cannot create initial context");
+
+                ejbHome = getEJBHome(context, beanJndiName);
+
+                if (ejbHome == null)
+                    throw new AxisFault("cannot find jndi home");
+            }
+            catch (Exception exception) {
+                throw AxisFault.makeFault(exception);
+            }
+
+            return ejbHome;
+        }
+
+        private InitialContext getCachedContext()
+                throws javax.naming.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));
+        }
+
+        private Object getEJBHome(InitialContext context, String beanJndiName)
+                throws AxisFault, javax.naming.NamingException {
+            return context.lookup(beanJndiName);
+        }
+
+        private ClassLoader getContextClassLoader() {
+            return (ClassLoader) AccessController.doPrivileged(
+                    new PrivilegedAction() {
+                        public Object run() {
+                            return Thread.currentThread().getContextClassLoader();
+                        }
+                    }
+            );
+        }
+
+        public Exception getException() {
+            return exception;
+        }
+
+        public Object getReturnedValue() {
+            return returnedValue;
+        }
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org