Title: [2481] trunk/openejb1: EJB over HTTP works in a Tomcat/OpenEJB integration

Diff

Modified: trunk/openejb1/maven.xml (2480 => 2481)

--- trunk/openejb1/maven.xml	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/maven.xml	2006-02-22 17:52:11 UTC (rev 2481)
@@ -531,18 +531,21 @@
       <j:set var="tomcat.branch" value="5"/>
       <j:set var="tomcat.version" value="5.5.15"/>
       <j:set var="tomcat.prefix" value="apache"/>
+      <attainGoal name="tomcat.env"/>
     </goal>
 
     <goal name="tomcat50">
       <j:set var="tomcat.branch" value="5"/>
       <j:set var="tomcat.version" value="5.0.30"/>
       <j:set var="tomcat.prefix" value="jakarta"/>
+      <attainGoal name="tomcat.env"/>
     </goal>
 
     <goal name="tomcat4">
       <j:set var="tomcat.branch" value="4"/>
       <j:set var="tomcat.version" value="4.1.31"/>
       <j:set var="tomcat.prefix" value="jakarta"/>
+      <attainGoal name="tomcat.env"/>
     </goal>
 
     <goal name="setup:tomcat">
@@ -613,6 +616,11 @@
       <exec executable="${tomcat.home}/bin/shutdown.sh" />
     </goal>
 
+    <goal name="tomcat.env">
+      <j:set var="targetDir" value="${basedir}/target/"/>
+      <j:set var="tomcat.home" value="${targetDir}/${tomcat.prefix}-tomcat-${tomcat.version}"/>
+      <j:set var="openejb.home" value="${targetDir}/openejb-${pom.currentVersion}" />
+    </goal>
 
     <goal name="setup:loader-webapp">
       <!-- Unzip webapp and set openejb.home -->
@@ -621,6 +629,9 @@
       <replace file="${tomcat.home}/webapps/openejb/WEB-INF/web.xml" token="@OPENEJB_HOME@" value="${openejb.home}"/>
     </goal>
     <goal name="setup:webapp-example">
+      <j:set var="targetDir" value="${basedir}/target/"/>
+      <j:set var="tomcat.home" value="${targetDir}/${tomcat.prefix}-tomcat-${tomcat.version}"/>
+      <j:set var="openejb.home" value="${targetDir}/openejb-${pom.currentVersion}" />
       <!-- Unzip webapp and set openejb.home -->
       <mkdir dir="${tomcat.home}/webapps/openejb"/>
       <unjar src="" dest="${tomcat.home}/webapps/movies"/>

Modified: trunk/openejb1/modules/core/src/bin/openejb (2480 => 2481)

--- trunk/openejb1/modules/core/src/bin/openejb	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/core/src/bin/openejb	2006-02-22 17:52:11 UTC (rev 2481)
@@ -123,6 +123,11 @@
    java -jar $OPENEJB_HOME/lib/openejb-core-*.jar test http
 }
 #============================================================
+_test_tomcat()
+{
+   java -jar $OPENEJB_HOME/lib/openejb-core-*.jar test tomcat
+}
+#============================================================
 _command_test()
 {
 case $2 in
@@ -135,6 +140,9 @@
     "http")
         _test_http
     ;;
+    "tomcat")
+        _test_tomcat
+    ;;
     "--help")
         _test_help
     ;;

Added: trunk/openejb1/modules/core/src/java/org/openejb/loader/Embedder.java (2480 => 2481)

--- trunk/openejb1/modules/core/src/java/org/openejb/loader/Embedder.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/core/src/java/org/openejb/loader/Embedder.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -0,0 +1,124 @@
+/**
+ *
+ * Copyright 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.
+ */
+package org.openejb.loader;
+
+import org.openejb.util.FileUtils;
+
+import java.io.File;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class Embedder {
+
+    private final String className;
+
+    public Embedder(String className) {
+        this.className = className;
+    }
+
+    public Class load() throws Exception {
+        ClassPath classPath = SystemInstance.get().getClassPath();
+        ClassLoader classLoader = classPath.getClassLoader();
+        try {
+            return  classLoader.loadClass(className);
+        } catch (Exception e) {
+            return forcefulLoad(classPath, classLoader);
+        }
+    }
+
+    private Class forcefulLoad(ClassPath classPath, ClassLoader classLoader) throws Exception {
+        try {
+            checkOpenEjbHome(SystemInstance.get().getHome().getDirectory());
+            FileUtils home = SystemInstance.get().getHome();
+            classPath.addJarsToPath(home.getDirectory("lib"));
+        } catch (Exception e2) {
+            throw new Exception("Could not load OpenEJB libraries. Exception: " + e2.getClass().getName() + " " + e2.getMessage());
+        }
+        try {
+            return classLoader.loadClass(className);
+        } catch (Exception e2) {
+            throw new Exception("Could not load class '"+className+"' after embedding libraries. Exception: " + e2.getClass().getName() + " " + e2.getMessage());
+        }
+    }
+
+    private String NO_HOME = "The openejb.home is not set.";
+
+    private String BAD_HOME = "Invalid openejb.home: ";
+
+    private String NOT_THERE = "The path specified does not exist.";
+
+    private String NOT_DIRECTORY = "The path specified is not a directory.";
+
+    private String NO_DIST = "The path specified is not correct, it does not contain a 'dist' directory.";
+
+    private String NO_LIBS = "The path specified is not correct, it does not contain any OpenEJB libraries.";
+
+    // TODO: move this part back into the LoaderServlet
+    private String INSTRUCTIONS = "Please edit the web.xml of the openejb_loader webapp and set the openejb.home init-param to the full path where OpenEJB is installed.";
+
+    private void checkOpenEjbHome(File openejbHome) throws Exception {
+        try {
+
+            String homePath = openejbHome.getAbsolutePath();
+
+            // The openejb.home must exist
+            if (!openejbHome.exists())
+                handleError(BAD_HOME + homePath, NOT_THERE, INSTRUCTIONS);
+
+            // The openejb.home must be a directory
+            if (!openejbHome.isDirectory())
+                handleError(BAD_HOME + homePath, NOT_DIRECTORY, INSTRUCTIONS);
+
+            // The openejb.home must contain a 'lib' directory
+            File openejbHomeLibs = new File(openejbHome, "lib");
+            if (!openejbHomeLibs.exists())
+                handleError(BAD_HOME + homePath, NO_DIST, INSTRUCTIONS);
+
+            // The openejb.home there must be openejb*.jar files in the 'dist'
+            // directory
+            String[] libs = openejbHomeLibs.list();
+            boolean found = false;
+            for (int i = 0; i < libs.length && !found; i++) {
+                found = (libs[i].startsWith("openejb-") && libs[i].endsWith(".jar"));
+            }
+            if (!found)
+                handleError(BAD_HOME + homePath, NO_LIBS, INSTRUCTIONS);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void handleError(String m1, String m2, String m3) throws Exception {
+        System.err.println("--[PLEASE FIX]-------------------------------------");
+        System.err.println(m1);
+        System.err.println(m2);
+        System.err.println(m3);
+        System.err.println("---------------------------------------------------");
+        throw new Exception(m1 + " " + m2 + " " + m3);
+    }
+
+    private void handleError(String m1, String m2) throws Exception {
+        System.err.println("--[PLEASE FIX]-------------------------------------");
+        System.err.println(m1);
+        System.err.println(m2);
+        System.err.println("---------------------------------------------------");
+        throw new Exception(m1 + " " + m2);
+    }
+
+}

Modified: trunk/openejb1/modules/core/src/java/org/openejb/loader/Loader.java (2480 => 2481)

--- trunk/openejb1/modules/core/src/java/org/openejb/loader/Loader.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/core/src/java/org/openejb/loader/Loader.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -44,16 +44,20 @@
  */
 package org.openejb.loader;
 
-import java.util.Hashtable;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 
 /**
- * 
  * @author <a href="" PROTECTED]">David Blevins</a>
  */
 public interface Loader {
-    
-    public void load( Hashtable env ) throws Exception;
-    
+
+    public void init(ServletConfig servletConfig) throws ServletException;
+
+    void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
 }
 
  

Modified: trunk/openejb1/modules/core/src/java/org/openejb/loader/LoaderServlet.java (2480 => 2481)

--- trunk/openejb1/modules/core/src/java/org/openejb/loader/LoaderServlet.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/core/src/java/org/openejb/loader/LoaderServlet.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -44,30 +44,83 @@
  */
 package org.openejb.loader;
 
-import org.openejb.util.FileUtils;
-
 import java.io.File;
+import java.io.IOException;
 import java.util.Enumeration;
 import java.util.Properties;
 import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 
-import javax.naming.Context;
-import javax.naming.InitialContext;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
 /**
  * @author <a href="" PROTECTED]">David Blevins </a>
  */
 public class LoaderServlet extends HttpServlet {
-    private OpenEJBInstance openejb;
 
+    private Loader loader;
+
     public void init(ServletConfig config) throws ServletException {
+        if (loader != null) {
+            return;
+        }
+
+        // Do just enough to get the Tomcat Loader into the classpath
+        // let it do the rest.
+        Properties p = initParamsToProperties(config);
+
+        String embeddingStyle = p.getProperty("openejb.loader");
+
+        // Set the mandatory values for a webapp-only setup
+        if (embeddingStyle.endsWith("tomcat-webapp")) {
+            setPropertyIfNUll(p, "openejb.base", getWebappPath(config));
+//            setPropertyIfNUll(p, "openejb.configuration", "META-INF/openejb.xml");
+//            setPropertyIfNUll(p, "openejb.container.decorators", "org.openejb.tomcat.TomcatJndiSupport");
+//            setPropertyIfNUll(p, "log4j.configuration", "META-INF/log4j.properties");
+        }
+
+        try {
+            SystemInstance.init(p);
+            Embedder embedder = new Embedder("org.openejb.tomcat.TomcatLoader");
+            Class loaderClass = embedder.load();
+            Object instance = loaderClass.newInstance();
+            try {
+                loader = (Loader) instance;
+            } catch (ClassCastException e) {
+                loader = new LoaderWrapper(instance);
+            }
+
+            loader.init(config);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        loader.service(request, response);
+    }
+
+    private String getWebappPath(ServletConfig config) {
+        ServletContext ctx = config.getServletContext();
+        File webInf = new File(ctx.getRealPath("WEB-INF"));
+        File webapp = webInf.getParentFile();
+        String webappPath = webapp.getAbsolutePath();
+        return webappPath;
+    }
+
+    private Properties initParamsToProperties(ServletConfig config) {
         Properties p = new Properties();
+
+        // Set some defaults
         p.setProperty("openejb.loader","tomcat");
 
+        // Load in each init-param as a property
         Enumeration enum = config.getInitParameterNames();
         System.out.println("OpenEJB init-params:");
         while (enum.hasMoreElements()) {
@@ -77,34 +130,9 @@
             System.out.println("\tparam-name: " + name + ", param-value: " + value);
         }
 
-        String loader = p.getProperty("openejb.loader"); // Default loader set above
-        if (loader.endsWith("tomcat-webapp")) {
-            ServletContext ctx = config.getServletContext();
-            File webInf = new File(ctx.getRealPath("WEB-INF"));
-            File webapp = webInf.getParentFile();
-            String webappPath = webapp.getAbsolutePath();
-
-            setPropertyIfNUll(p, "openejb.base", webappPath);
-            setPropertyIfNUll(p, "openejb.configuration", "META-INF/openejb.xml");
-            setPropertyIfNUll(p, "openejb.container.decorators", "org.openejb.core.TomcatJndiSupport");
-            setPropertyIfNUll(p, "log4j.configuration", "META-INF/log4j.properties");
-        }
-
-        try {
-            init(p);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        return p;
     }
 
-    public void init(Properties properties) throws Exception {
-        if (openejb != null) return;
-        SystemInstance.init(properties);
-        openejb = new OpenEJBInstance();
-        if (openejb.isInitialized()) return;
-        openejb.init(properties);
-    }
-
     private Object setPropertyIfNUll(Properties properties, String key, String value){
         String currentValue = properties.getProperty(key);
         if (currentValue == null){
@@ -112,4 +140,66 @@
         }
         return currentValue;
     }
+
+    /**
+     * Ain't classloaders fun?
+     * This class exists to reconcile that loader implementations
+     * may exist in the parent classloader while the loader interface
+     * is also in this classloader.  Use this class in the event that
+     * this is the case.
+     * Think of this as an adapter for adapting the parent's idea of a
+     * Loader to our idea of a Loader.
+     */
+    public static class LoaderWrapper implements Loader {
+        private final Object loader;
+        private final Method init;
+        private final Method service;
+
+        public LoaderWrapper(Object loader)  {
+            this.loader = loader;
+            try {
+                Class loaderClass = loader.getClass();
+                this.init = loaderClass.getMethod("init", new Class[]{ServletConfig.class});
+                this.service = loaderClass.getMethod("service", new Class[]{HttpServletRequest.class, HttpServletResponse.class});
+            } catch (NoSuchMethodException e) {
+                throw (IllegalStateException) new IllegalStateException("Signatures for Loader are no longer correct.").initCause(e);
+            }
+        }
+
+        public void init(ServletConfig servletConfig) throws ServletException {
+            try {
+                init.invoke(loader, new Object[]{servletConfig});
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                } else if (cause instanceof Error) {
+                    throw (Error) cause;
+                } else {
+                    throw (ServletException) cause;
+                }
+            } catch (Exception e) {
+                throw new RuntimeException("Loader.init: "+e.getMessage()+e.getClass().getName()+": "+e.getMessage(), e);
+            }
+        }
+
+        public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+            try {
+                service.invoke(loader, new Object[]{request, response});
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                } else if (cause instanceof Error) {
+                    throw (Error) cause;
+                } else if (cause instanceof IOException) {
+                    throw (IOException) cause;
+                } else {
+                    throw (ServletException) cause;
+                }
+            } catch (Exception e) {
+                throw new RuntimeException("Loader.service: "+e.getMessage()+e.getClass().getName()+": "+e.getMessage(), e);
+            }
+        }
+    }
 }

Deleted: trunk/openejb1/modules/core/src/java/org/openejb/loader/package.html (2480 => 2481)

--- trunk/openejb1/modules/core/src/java/org/openejb/loader/package.html	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/core/src/java/org/openejb/loader/package.html	2006-02-22 17:52:11 UTC (rev 2481)
@@ -1,74 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-
-  Redistribution and use of this software and associated documentation
-  ("Software"), with or without modification, are permitted provided
-  that the following conditions are met:
-
-  1. Redistributions of source code must retain copyright
-     statements and notices.  Redistributions must also contain a
-     copy of this document.
-
-  2. Redistributions in binary form must reproduce the
-     above copyright notice, this list of conditions and the
-     following disclaimer in the documentation and/or other
-     materials provided with the distribution.
-
-  3. The name "Exolab" must not be used to endorse or promote
-     products derived from this Software without prior written
-     permission of Exoffice Technologies.  For written permission,
-     please contact [EMAIL PROTECTED]
-
-  4. Products derived from this Software may not be called "Exolab"
-     nor may "Exolab" appear in their names without prior written
-     permission of Exoffice Technologies. Exolab is a registered
-     trademark of Exoffice Technologies.
-
-  5. Due credit should be given to the Exolab Project
-     (http://www.exolab.org/).
-
-  THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
-  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
-  EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-  OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
-
-  $Id$
-
--->
-</head>
-<body bgcolor="white">
-
-The classes and interfaces directly under this package define the OpenEJB Tomcat classPathathath.
-
-
-<h2>Package Specification</h2>
-
-Yet to come.
-
-<h2>Related Documentation</h2>
-
-<ul>
-  <li><a href="" website</a>
-  <li><a href="" Datasheet</a>
-  <li>Not subscribed to the mailing list?  <a href="" target="_blank">Subscribe me!</a>
-</ul>
-
-<!-- Put @see and @since tags down here. -->
[EMAIL PROTECTED] org.openejb.OpenEJB
[EMAIL PROTECTED] org.openejb.core.ContainerSystem
[EMAIL PROTECTED] org.openejb.Container
[EMAIL PROTECTED] org.openejb.DeploymentInfo
-</body>
-</html>

Added: trunk/openejb1/modules/core/src/java/org/openejb/tomcat/TomcatJndiSupport.java (2480 => 2481)

--- trunk/openejb1/modules/core/src/java/org/openejb/tomcat/TomcatJndiSupport.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/core/src/java/org/openejb/tomcat/TomcatJndiSupport.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -0,0 +1,163 @@
+/**
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact [EMAIL PROTECTED]
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2005 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: TomcatJndiSupport.java 2106 2005-08-26 21:04:51Z dblevins $
+ */
+
+package org.openejb.tomcat;
+
+import org.openejb.OpenEJBException;
+import org.openejb.RpcContainer;
+import org.openejb.core.RpcContainerWrapper;
+import org.openejb.core.DeploymentInfo;
+
+import javax.naming.Context;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Map;
+
+/**
+ * @version $Revision: 2106 $ $Date: 2005-08-26 14:04:51 -0700 (Fri, 26 Aug 2005) $
+ */
+public class TomcatJndiSupport extends RpcContainerWrapper {
+    private final Class contextBindings;
+    private final Method bindContext;
+    private final Method bindThread;
+    private final Method unbindThread;
+
+    public TomcatJndiSupport(RpcContainer container) throws OpenEJBException {
+        super(container);
+        try {
+            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+            contextBindings = classLoader.loadClass("org.apache.naming.ContextBindings");
+            bindContext = contextBindings.getMethod("bindContext", new Class[]{Object.class, Context.class, Object.class});
+            bindThread = contextBindings.getMethod("bindThread", new Class[]{Object.class, Object.class});
+            unbindThread = contextBindings.getMethod("unbindThread", new Class[]{Object.class, Object.class});
+        } catch (ClassNotFoundException e) {
+            throw new OpenEJBException("Unable to setup Tomcat JNDI support.  Support requires the org.apache.naming.ContextBindings class to be available.");
+        } catch (NoSuchMethodException e) {
+            throw new OpenEJBException("Unable to setup Tomcat JNDI support.  Method of org.apache.naming.ContextBindings was not found:"+e.getMessage());
+        }
+    }
+
+    public void init(Object containerId, HashMap deployments, Properties properties) throws OpenEJBException {
+        super.init(containerId, deployments, properties);
+        Collection collection = deployments.values();
+        for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+            DeploymentInfo deployment = (DeploymentInfo) iterator.next();
+
+            setupDeployment(deployment);
+        }
+    }
+
+    public void deploy(Object deploymentID, org.openejb.DeploymentInfo info) throws OpenEJBException {
+        super.deploy(deploymentID, info);
+        setupDeployment((DeploymentInfo)info);
+    }
+
+    public static Map contexts = new HashMap();
+
+    private void setupDeployment(DeploymentInfo deployment) {
+        // Set this container as the deployment's container
+        // so calls from proxies created by the deploymentinfo
+        // class come here first.
+        deployment.setContainer(this);
+
+        // Register this deployment's JNDI namespace in
+        // Tomcat's list of context objects
+        Object deploymentID = deployment.getDeploymentID();
+        Context jndiEnc = deployment.getJndiEnc();
+        bindContext(deploymentID, jndiEnc);
+        contexts.put(deploymentID, jndiEnc);
+    }
+
+    public Object invoke(Object deployID, Method callMethod, Object[] args, Object primKey, Object securityIdentity) throws OpenEJBException {
+        try {
+            // Tell tomcat that this deployment's context should
+            // be used for this call
+            bindThread(deployID);
+            return super.invoke(deployID, callMethod, args, primKey, securityIdentity);
+        } finally {
+            unbindThread(deployID);
+        }
+    }
+
+    public void bindContext(Object name, Context context) {
+        try {
+            bindContext.invoke(null, new Object[]{name, context, name});
+        } catch (Throwable e) {
+            throw convertToRuntimeException(e, "bindContext");
+        }
+    }
+
+    public void bindThread(Object name) {
+        try {
+            bindThread.invoke(null, new Object[]{name, name});
+        } catch (Throwable e) {
+            throw convertToRuntimeException(e, "bindThread");
+        }
+    }
+
+    public void unbindThread(Object name) {
+        try {
+            unbindThread.invoke(null, new Object[]{name, name});
+        } catch (Throwable e) {
+            throw convertToRuntimeException(e, "unbindThread");
+        }
+    }
+
+    private RuntimeException convertToRuntimeException(Throwable e, String methodName) {
+        if (e instanceof InvocationTargetException){
+            Throwable cause = e.getCause();
+            if (cause instanceof RuntimeException){
+                return (RuntimeException) cause;
+            } else {
+                e = cause;
+            }
+        }
+        return new RuntimeException("ContextBindings."+methodName, e);
+    }
+}

Added: trunk/openejb1/modules/core/src/java/org/openejb/tomcat/TomcatLoader.java (2480 => 2481)

--- trunk/openejb1/modules/core/src/java/org/openejb/tomcat/TomcatLoader.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/core/src/java/org/openejb/tomcat/TomcatLoader.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -0,0 +1,109 @@
+/**
+ *
+ * Copyright 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.
+ */
+package org.openejb.tomcat;
+
+import org.openejb.OpenEJB;
+import org.openejb.loader.Loader;
+import org.openejb.loader.SystemInstance;
+import org.openejb.server.ServerFederation;
+import org.openejb.server.ServiceException;
+import org.openejb.server.ejbd.EjbServer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class TomcatLoader implements Loader {
+
+    private EjbServer ejbServer;
+
+    public void init(ServletConfig config) throws ServletException {
+        // Not thread safe
+        if (OpenEJB.isInitialized()) {
+            ejbServer = (EjbServer) SystemInstance.get().getObject(this.ejbServer.getClass().getName());
+            return;
+        }
+
+        Properties p = new Properties();
+        p.setProperty("openejb.loader", "tomcat");
+
+        Enumeration enum = config.getInitParameterNames();
+        System.out.println("OpenEJB init-params:");
+        while (enum.hasMoreElements()) {
+            String name = (String) enum.nextElement();
+            String value = config.getInitParameter(name);
+            p.put(name, value);
+            System.out.println("\tparam-name: " + name + ", param-value: " + value);
+        }
+
+        String loader = p.getProperty("openejb.loader"); // Default loader set above
+        if (loader.endsWith("tomcat-webapp")) {
+            ServletContext ctx = config.getServletContext();
+            File webInf = new File(ctx.getRealPath("WEB-INF"));
+            File webapp = webInf.getParentFile();
+            String webappPath = webapp.getAbsolutePath();
+
+            setPropertyIfNUll(p, "openejb.base", webappPath);
+            setPropertyIfNUll(p, "openejb.configuration", "META-INF/openejb.xml");
+            setPropertyIfNUll(p, "openejb.container.decorators", TomcatJndiSupport.class.getName());
+            setPropertyIfNUll(p, "log4j.configuration", "META-INF/log4j.properties");
+        }
+
+        try {
+            init(p);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void init(Properties props) throws Exception {
+        SystemInstance.init(props);
+        ejbServer = new EjbServer();
+        SystemInstance.get().setObject(ejbServer.getClass().getName(), ejbServer);
+        OpenEJB.init(props, new ServerFederation());
+        ejbServer.init(props);
+    }
+
+    private Object setPropertyIfNUll(Properties properties, String key, String value) {
+        String currentValue = properties.getProperty(key);
+        if (currentValue == null) {
+            properties.setProperty(key, value);
+        }
+        return currentValue;
+    }
+
+    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        ServletInputStream in = request.getInputStream();
+        ServletOutputStream out = response.getOutputStream();
+        try {
+            ejbServer.service(in, out);
+        } catch (ServiceException e) {
+            throw new ServletException("ServerService error: " + ejbServer.getClass().getName() + " -- " + e.getMessage(), e);
+        }
+    }
+}

Modified: trunk/openejb1/modules/itests/src/java/org/openejb/test/RemoteHttpTestServer.java (2480 => 2481)

--- trunk/openejb1/modules/itests/src/java/org/openejb/test/RemoteHttpTestServer.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/itests/src/java/org/openejb/test/RemoteHttpTestServer.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -30,4 +30,5 @@
         props.put("java.naming.factory.initial", RemoteInitialContextFactory.class.getName());
         props.put("java.naming.provider.url","http://127.0.0.1:4204");
     }
+
 }

Modified: trunk/openejb1/modules/itests/src/java/org/openejb/test/TestRunner.java (2480 => 2481)

--- trunk/openejb1/modules/itests/src/java/org/openejb/test/TestRunner.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/itests/src/java/org/openejb/test/TestRunner.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -56,7 +56,7 @@
 import org.openejb.util.JarUtils;
 
 /**
- * 
+ *
  * @author <a href="" PROTECTED]">David Blevins</a>
  * @author <a href="" PROTECTED]">Richard Monson-Haefel</a>
  */
@@ -101,6 +101,8 @@
 				runRemoteTests();
 			} else if (args[0].equals("http")) {
 				runRemoteHttpTests();
+			} else if (args[0].equals("tomcat")) {
+				runTomcatRemoteHttpTests();
 			} else {
 				printHelp();
 
@@ -160,6 +162,17 @@
 		System.out.println("_________________________________________________");
 	}
 
+	private static void runTomcatRemoteHttpTests() {
+		System.setProperty("openejb.test.server", TomcatRemoteTestServer.class.getName());
+		System.setProperty("openejb.test.database", "org.openejb.test.InstantDbTestDatabase");
+
+		System.out.println("_________________________________________________");
+		System.out
+				.println("|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|\n");
+		System.out.println("Running EJB compliance tests on HTTP/Tomcat Server");
+		System.out.println("_________________________________________________");
+	}
+
 	private static void printHelp() {
 		String header = "OpenEJB Compliance Tests ";
 		try {

Added: trunk/openejb1/modules/itests/src/java/org/openejb/test/TomcatRemoteTestServer.java (2480 => 2481)

--- trunk/openejb1/modules/itests/src/java/org/openejb/test/TomcatRemoteTestServer.java	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/itests/src/java/org/openejb/test/TomcatRemoteTestServer.java	2006-02-22 17:52:11 UTC (rev 2481)
@@ -0,0 +1,47 @@
+/**
+ *
+ * Copyright 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.
+ */
+package org.openejb.test;
+
+import org.openejb.client.RemoteInitialContextFactory;
+
+import java.util.Properties;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class TomcatRemoteTestServer implements TestServer {
+    private Properties properties;
+
+    public void init(Properties props) {
+        properties = props;
+        props.put("test.server.class", TomcatRemoteTestServer.class.getName());
+        props.put("java.naming.factory.initial", RemoteInitialContextFactory.class.getName());
+        props.put("java.naming.provider.url","http://127.0.0.1:8080/openejb/remote");
+    }
+
+    public void start() {
+        System.out.println("Note: Tomcat should be started before running these tests");
+    }
+
+    public void stop() {
+    }
+
+
+    public Properties getContextEnvironment(){
+        return (Properties)properties.clone();
+    }
+}

Modified: trunk/openejb1/modules/webadmin/src/webapp/WEB-INF/web.xml (2480 => 2481)

--- trunk/openejb1/modules/webadmin/src/webapp/WEB-INF/web.xml	2006-02-21 21:26:15 UTC (rev 2480)
+++ trunk/openejb1/modules/webadmin/src/webapp/WEB-INF/web.xml	2006-02-22 17:52:11 UTC (rev 2481)
@@ -68,7 +68,12 @@
     -->
     
     <load-on-startup>0</load-on-startup>
-  
+
   </servlet>
 
+  <servlet-mapping>
+    <servlet-name>loader</servlet-name>
+    <url-pattern>/remote/*</url-pattern>
+  </servlet-mapping>
+
 </web-app>

Reply via email to