You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2015/03/24 08:54:05 UTC

tomee git commit: TOMEE-1511 tolerating parallel deployments for jaxws

Repository: tomee
Updated Branches:
  refs/heads/master d60d52322 -> ce4c7ce45


TOMEE-1511 tolerating parallel deployments for jaxws


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/ce4c7ce4
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/ce4c7ce4
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/ce4c7ce4

Branch: refs/heads/master
Commit: ce4c7ce454651660d58d88fe73f5f1cf5e81180a
Parents: d60d523
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Tue Mar 24 08:53:55 2015 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Tue Mar 24 08:53:55 2015 +0100

----------------------------------------------------------------------
 .../openejb/monitoring/LocalMBeanServer.java    |   4 +-
 .../webservices/OpenEJBHttpWsRegistry.java      |  14 ++-
 .../openejb/server/webservices/WsRegistry.java  |  10 +-
 .../openejb/server/webservices/WsService.java   |  21 ++--
 .../tomee/webservices/TomcatWsRegistry.java     | 115 ++++++++++++++-----
 5 files changed, 117 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/ce4c7ce4/container/openejb-core/src/main/java/org/apache/openejb/monitoring/LocalMBeanServer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/monitoring/LocalMBeanServer.java b/container/openejb-core/src/main/java/org/apache/openejb/monitoring/LocalMBeanServer.java
index 51d0d94..94b3b2f 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/monitoring/LocalMBeanServer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/monitoring/LocalMBeanServer.java
@@ -89,7 +89,7 @@ public final class LocalMBeanServer implements MBeanServer {
             return get().registerMBean(mbean, name);
 
         } catch (final Exception e) {
-            LOGGER.error("Cannot register MBean " + name, e);
+            LOGGER.error("Cannot register MBean " + name); // silently so no stack
         }
         return null;
     }
@@ -103,7 +103,7 @@ public final class LocalMBeanServer implements MBeanServer {
             get().unregisterMBean(name);
 
         } catch (final Exception e) {
-            LOGGER.error("Cannot unregister MBean " + name, e);
+            LOGGER.error("Cannot unregister MBean " + name); // silently so no stack
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/ce4c7ce4/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
----------------------------------------------------------------------
diff --git a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
index c9e2218..bfd0abd 100644
--- a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
+++ b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
@@ -29,16 +29,17 @@ public class OpenEJBHttpWsRegistry extends OpenEJBHttpRegistry implements WsRegi
     public List<String> setWsContainer(final HttpListener httpListener,
                                        final ClassLoader classLoader,
                                        final String context, final String virtualHost, final ServletInfo servletInfo,
-                                       final String realmName, final String transportGuarantee, final String authMethod) throws Exception {
+                                       final String realmName, final String transportGuarantee, final String authMethod,
+                                       final String moduleId) throws Exception {
 
         final String path = servletInfo.mappings.iterator().next();
-        return addWsContainer(httpListener, classLoader, context, virtualHost, path, realmName, transportGuarantee, authMethod);
+        return addWsContainer(httpListener, classLoader, context, virtualHost, path, realmName, transportGuarantee, authMethod, moduleId);
     }
 
     @Override
-    public void clearWsContainer(final String context, final String virtualHost, final ServletInfo servletInfo) {
+    public void clearWsContainer(final String context, final String virtualHost, final ServletInfo servletInfo, final String moduleId) {
         final String path = servletInfo.mappings.iterator().next();
-        removeWsContainer(path);
+        removeWsContainer(path, moduleId);
     }
 
     @Override
@@ -49,7 +50,8 @@ public class OpenEJBHttpWsRegistry extends OpenEJBHttpRegistry implements WsRegi
                                        final String path,
                                        final String realmName,
                                        final String transportGuarantee, // ignored
-                                       final String authMethod) throws Exception {
+                                       final String authMethod,
+                                       final String moduleId) throws Exception {
 
         if (path == null) throw new NullPointerException("contextRoot is null");
 
@@ -84,7 +86,7 @@ public class OpenEJBHttpWsRegistry extends OpenEJBHttpRegistry implements WsRegi
     }
 
     @Override
-    public void removeWsContainer(final String path) {
+    public void removeWsContainer(final String path, final String moduleId) {
         registry.removeHttpListener(path);
     }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/ce4c7ce4/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsRegistry.java
----------------------------------------------------------------------
diff --git a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsRegistry.java b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsRegistry.java
index e9db64f..ed4a3df 100644
--- a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsRegistry.java
+++ b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsRegistry.java
@@ -25,9 +25,10 @@ public interface WsRegistry {
     List<String> setWsContainer(HttpListener httpListener,
                                 ClassLoader classLoader,
                                 String context, String virtualHost, ServletInfo servletInfo,
-                                String realmName, String transportGuarantee, String authMethod) throws Exception;
+                                String realmName, String transportGuarantee, String authMethod,
+                                String moduleId) throws Exception;
 
-    void clearWsContainer(String context, String virtualHost, ServletInfo servletInfo);
+    void clearWsContainer(String context, String virtualHost, ServletInfo servletInfo, String moduleId);
 
     List<String> addWsContainer(HttpListener inputListener,
                                 ClassLoader classLoader,
@@ -36,7 +37,8 @@ public interface WsRegistry {
                                 String path,
                                 String realmName,
                                 String transportGuarantee, // ignored
-                                String authMethod) throws Exception;
+                                String authMethod,
+                                String moduleId) throws Exception;
 
-    void removeWsContainer(String path);
+    void removeWsContainer(String path, String moduleId);
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/ce4c7ce4/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java
----------------------------------------------------------------------
diff --git a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java
index 07e768b..3485f01 100644
--- a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java
+++ b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java
@@ -238,17 +238,17 @@ public abstract class WsService implements ServerService, SelfManaging {
     private void deployApp(final AppInfo appInfo, final Collection<BeanContext> ejbs) {
         final Collection<BeanContext> alreadyDeployed = deployedApplications.get(appInfo);
 
-        final Map<String, String> webContextByEjb = new HashMap<String, String>();
+        final Map<String, WebAppInfo> webContextByEjb = new HashMap<>();
         for (final WebAppInfo webApp : appInfo.webApps) {
             for (final String ejb : webApp.ejbWebServices) {
-                webContextByEjb.put(ejb, webApp.contextRoot);
+                webContextByEjb.put(ejb, webApp);
             }
         }
 
-        final Map<String, String> contextData = new HashMap<String, String>();
+        final Map<String, String> contextData = new HashMap<>();
         contextData.put("appId", appInfo.path);
         for (final EjbJarInfo ejbJar : appInfo.ejbJars) {
-            final Map<String, PortInfo> ports = new TreeMap<String, PortInfo>();
+            final Map<String, PortInfo> ports = new TreeMap<>();
             for (final PortInfo port : ejbJar.portInfos) {
                 ports.put(port.serviceLink, port);
             }
@@ -312,12 +312,15 @@ public abstract class WsService implements ServerService, SelfManaging {
                                 transport = portInfo.transportGuarantee;
                             }
 
-                            String context = webContextByEjb.get(bean.ejbClass);
+                            final WebAppInfo webAppInfo = webContextByEjb.get(bean.ejbClass);
+                            String context = webAppInfo != null ? webAppInfo.contextRoot : null;
+                            String moduleId = webAppInfo != null ? webAppInfo.moduleId : null;
                             if (context == null && !OLD_WEBSERVICE_DEPLOYMENT) {
                                 context = ejbJar.moduleName;
+                                context = null;
                             }
 
-                            final List<String> addresses = wsRegistry.addWsContainer(container, classLoader, context, host, location, realm, transport, auth);
+                            final List<String> addresses = wsRegistry.addWsContainer(container, classLoader, context, host, location, realm, transport, auth, moduleId);
                             alreadyDeployed.add(beanContext);
 
                             // one of the registered addresses to be the canonical address
@@ -431,7 +434,7 @@ public abstract class WsService implements ServerService, SelfManaging {
                     }
 
                     // give servlet a reference to the webservice container
-                    final List<String> addresses = wsRegistry.setWsContainer(container, classLoader, webApp.contextRoot, host(webApp), servlet, realm, transport, auth);
+                    final List<String> addresses = wsRegistry.setWsContainer(container, classLoader, webApp.contextRoot, host(webApp), servlet, realm, transport, auth, webApp.moduleId);
 
                     // one of the registered addresses to be the connonical address
                     final String address = HttpUtil.selectSingleAddress(addresses);
@@ -488,7 +491,7 @@ public abstract class WsService implements ServerService, SelfManaging {
                         // remove container from web server
                         final String location = ejbLocations.get(enterpriseBean.ejbDeploymentId);
                         if (this.wsRegistry != null && location != null) {
-                            this.wsRegistry.removeWsContainer(location);
+                            this.wsRegistry.removeWsContainer(location, ejbJar.moduleId);
                         }
 
                         // destroy webservice container
@@ -528,7 +531,7 @@ public abstract class WsService implements ServerService, SelfManaging {
                     // clear servlet's reference to the webservice container
                     if (this.wsRegistry != null) {
                         try {
-                            this.wsRegistry.clearWsContainer(webApp.contextRoot, host(webApp), servlet);
+                            this.wsRegistry.clearWsContainer(webApp.contextRoot, host(webApp), servlet, webApp.moduleId);
                         } catch (final IllegalArgumentException ignored) {
                             // no-op
                         }

http://git-wip-us.apache.org/repos/asf/tomee/blob/ce4c7ce4/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java b/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
index eedbaf4..b33976f 100644
--- a/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
+++ b/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
@@ -52,7 +52,9 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static java.util.Arrays.asList;
 
 public class TomcatWsRegistry implements WsRegistry {
     private static final String WEBSERVICE_SUB_CONTEXT = forceSlash(SystemInstance.get().getOptions().get("tomee.jaxws.subcontext", "/webservices"));
@@ -60,8 +62,8 @@ public class TomcatWsRegistry implements WsRegistry {
     private static final boolean WEBSERVICE_OLDCONTEXT_ACTIVE = SystemInstance.get().getOptions().get("tomee.jaxws.oldsubcontext", false);
     private static final String TOMEE_JAXWS_SECURITY_ROLE_PREFIX = "tomee.jaxws.security-role.";
 
-    private final Map<String, Context> webserviceContexts = new TreeMap<String, Context>();
-    private final Map<String, Integer> fakeContextReferences = new TreeMap<String, Integer>();
+    private final Map<Key, Context> webserviceContexts = new ConcurrentHashMap<>();
+    private final Map<String, Integer> fakeContextReferences = new ConcurrentHashMap<>();
 
     private Engine engine;
     private List<Connector> connectors;
@@ -92,7 +94,8 @@ public class TomcatWsRegistry implements WsRegistry {
     public List<String> setWsContainer(final HttpListener httpListener,
                                        final ClassLoader classLoader,
                                        String contextRoot, String virtualHost, final ServletInfo servletInfo,
-                                       final String realmName, final String transportGuarantee, final String authMethod) throws Exception {
+                                       final String realmName, final String transportGuarantee, final String authMethod,
+                                       final String moduleId) throws Exception {
 
         if (virtualHost == null) {
             virtualHost = engine.getDefaultHost();
@@ -133,7 +136,7 @@ public class TomcatWsRegistry implements WsRegistry {
         setWsContainer(context, wrapper, httpListener);
 
         // add service locations
-        final List<String> addresses = new ArrayList<String>();
+        final List<String> addresses = new ArrayList<>();
         for (final Connector connector : connectors) {
             for (final String mapping : wrapper.findMappings()) {
                 final URI address = new URI(connector.getScheme(), null, host.getName(), connector.getPort(), (contextRoot.startsWith("/") ? "" : "/") + contextRoot + mapping, null, null);
@@ -145,7 +148,7 @@ public class TomcatWsRegistry implements WsRegistry {
 
 
     @Override
-    public void clearWsContainer(final String contextRoot, String virtualHost, final ServletInfo servletInfo) {
+    public void clearWsContainer(final String contextRoot, String virtualHost, final ServletInfo servletInfo, final String moduleId) {
         if (virtualHost == null) {
             virtualHost = engine.getDefaultHost();
         }
@@ -180,7 +183,8 @@ public class TomcatWsRegistry implements WsRegistry {
     public List<String> addWsContainer(final HttpListener httpListener,
                                        final ClassLoader classLoader,
                                        final String context, String virtualHost, String path,
-                                       final String realmName, final String transportGuarantee, final String authMethod) throws Exception {
+                                       final String realmName, final String transportGuarantee, final String authMethod,
+                                       final String moduleId) throws Exception {
         if (path == null) {
             throw new NullPointerException("contextRoot is null");
         }
@@ -202,7 +206,7 @@ public class TomcatWsRegistry implements WsRegistry {
             throw new IllegalArgumentException("Invalid virtual host '" + virtualHost + "'.  Do you have a matchiing Host entry in the server.xml?");
         }
 
-        final List<String> addresses = new ArrayList<String>();
+        final List<String> addresses = new ArrayList<>();
 
         // build contexts
         // - old way (/*)
@@ -212,23 +216,16 @@ public class TomcatWsRegistry implements WsRegistry {
 
         // - new way (/<webappcontext>/webservices/<name>) if webcontext is specified
         if (context != null) {
-            String root = context;
-            if ("ROOT".equals(root)) {
-                root = "";
-            }
-            if (!root.startsWith("/") && !root.isEmpty()) {
-                root = '/' + root;
-            }
+            final Context webAppContext = findContext(context, moduleId, host);
 
-            final Context webAppContext = Context.class.cast(host.findChild(root));
             if (webAppContext != null) {
                 // sub context = '/' means the service address is provided by webservices
                 if (WEBSERVICE_SUB_CONTEXT.equals("/") && path.startsWith("/")) {
-                    addServlet(host, webAppContext, path, httpListener, path, addresses, false);
+                    addServlet(host, webAppContext, path, httpListener, path, addresses, false, moduleId);
                 } else if (WEBSERVICE_SUB_CONTEXT.equals("/") && !path.startsWith("/")) {
-                    addServlet(host, webAppContext, '/' + path, httpListener, path, addresses, false);
+                    addServlet(host, webAppContext, '/' + path, httpListener, path, addresses, false, moduleId);
                 } else {
-                    addServlet(host, webAppContext, WEBSERVICE_SUB_CONTEXT + path, httpListener, path, addresses, false);
+                    addServlet(host, webAppContext, WEBSERVICE_SUB_CONTEXT + path, httpListener, path, addresses, false, moduleId);
                 }
             } else if (!WEBSERVICE_OLDCONTEXT_ACTIVE) { // deploying in a jar
                 deployInFakeWebapp(path, classLoader, authMethod, transportGuarantee, realmName, host, httpListener, addresses, context);
@@ -237,7 +234,30 @@ public class TomcatWsRegistry implements WsRegistry {
         return addresses;
     }
 
-    private void deployInFakeWebapp(final String path, final ClassLoader classLoader, final String authMethod, final String transportGuarantee, final String realmName, final Container host, final HttpListener httpListener, final List<String> addresses, final String name) {
+    private Context findContext(final String context, final String moduleId, final Container host) {
+        String root = context;
+        if ("ROOT".equals(root)) {
+            root = "";
+        }
+        if (!root.startsWith("/") && !root.isEmpty()) {
+            root = '/' + root;
+        }
+
+        Context webAppContext = null;
+        for (final String name : asList(moduleId == null ? null : "/" + moduleId, root)) {
+            if (name == null) {
+                continue;
+            }
+            webAppContext = Context.class.cast(host.findChild(name));
+            if (webAppContext != null) {
+                break;
+            }
+        }
+        return webAppContext;
+    }
+
+    private void deployInFakeWebapp(final String path, final ClassLoader classLoader, final String authMethod, final String transportGuarantee,
+                                    final String realmName, final Container host, final HttpListener httpListener, final List<String> addresses, final String name) {
         Container context = host.findChild(name);
         if (context == null) {
             context = createNewContext(classLoader, authMethod, transportGuarantee, realmName, name);
@@ -255,7 +275,7 @@ public class TomcatWsRegistry implements WsRegistry {
         if (!mapping.startsWith("/")) { // TODO: check it can happen or move it away
             mapping = '/' + mapping;
         }
-        addServlet(host, (Context) context, mapping, httpListener, path, addresses, true);
+        addServlet(host, (Context) context, mapping, httpListener, path, addresses, true, null);
     }
 
     private static Context createNewContext(final ClassLoader classLoader, String authMethod, String transportGuarantee, final String realmName, final String name) {
@@ -331,7 +351,8 @@ public class TomcatWsRegistry implements WsRegistry {
         return context;
     }
 
-    private void addServlet(final Container host, final Context context, final String mapping, final HttpListener httpListener, final String path, final List<String> addresses, final boolean fakeDeployment) {
+    private void addServlet(final Container host, final Context context, final String mapping, final HttpListener httpListener, final String path,
+                            final List<String> addresses, final boolean fakeDeployment, final String moduleId) {
         // build the servlet
         final Wrapper wrapper = context.createWrapper();
         wrapper.setName("webservice" + path.substring(1));
@@ -346,13 +367,13 @@ public class TomcatWsRegistry implements WsRegistry {
 
         setWsContainer(context, wrapper, httpListener);
 
-        webserviceContexts.put(path, context);
+        webserviceContexts.put(new Key(path, moduleId), context);
 
         // register wsdl locations for service-ref resolution
         for (final Connector connector : connectors) {
             final StringBuilder fullContextpath;
             if (!WEBSERVICE_OLDCONTEXT_ACTIVE && !fakeDeployment) {
-                String contextPath = context.getName();
+                String contextPath = context.getPath();
                 if (contextPath == null ||  !contextPath.isEmpty()) {
                     if (contextPath != null && !contextPath.startsWith("/")) {
                         contextPath = "/" + contextPath;
@@ -379,7 +400,7 @@ public class TomcatWsRegistry implements WsRegistry {
         }
     }
 
-    public void removeWsContainer(String path) {
+    public void removeWsContainer(String path, final String moduleId) {
         if (path == null) {
             return;
         }
@@ -393,7 +414,11 @@ public class TomcatWsRegistry implements WsRegistry {
             return;
         }
 
-        final Context context = webserviceContexts.remove(path);
+        Context context = webserviceContexts.remove(new Key(path, moduleId));
+        if (context == null) { // fake
+            context = webserviceContexts.remove(new Key(path, null));
+        }
+
         Integer refs = 1; // > 0 to avoid to destroy the context if not mandatory
         if (context != null) {
             final String name = context.getName();
@@ -423,4 +448,42 @@ public class TomcatWsRegistry implements WsRegistry {
         context.getServletContext().setAttribute(webServicecontainerID, wsContainer);
         wrapper.addInitParameter(WsServlet.WEBSERVICE_CONTAINER, webServicecontainerID);
     }
+
+    private static class Key {
+        private final String moduleId;
+        private final String path;
+        private final int hash;
+
+        public Key(final String moduleId, final String path) {
+            this.moduleId = moduleId;
+            this.path = path;
+            this.hash = 31 * (moduleId != null ? moduleId.hashCode() : 0) + path.hashCode();
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || Key.class != o.getClass()) {
+                return false;
+            }
+
+            final Key key = Key.class.cast(o);
+            return !(moduleId != null ? !moduleId.equals(key.moduleId) : key.moduleId != null) && path.equals(key.path);
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public String toString() {
+            return "Key{" +
+                    "moduleId='" + moduleId + '\'' +
+                    ", path='" + path + '\'' +
+                    '}';
+        }
+    }
 }