Author: rmannibucau
Date: Thu Apr  3 20:12:57 2014
New Revision: 1584372

URL: http://svn.apache.org/r1584372
Log:
TOMEE-1164 forcing a parent classloader in tomcat webapp classloader

Added:
    tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/
    tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/
    tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/
    tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/
    
tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReloadingLoaderTest.java
Modified:
    
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
    tomee/tomee/trunk/tomee/tomee-jaxrs/pom.xml

Modified: 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java?rev=1584372&r1=1584371&r2=1584372&view=diff
==============================================================================
--- 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
 (original)
+++ 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
 Thu Apr  3 20:12:57 2014
@@ -16,47 +16,6 @@
  */
 package org.apache.tomee.catalina;
 
-import static org.apache.tomee.catalina.BackportUtil.getNamingContextListener;
-import static org.apache.tomee.catalina.Contexts.warPath;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-import javax.ejb.spi.HandleDelegate;
-import javax.el.ELResolver;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingException;
-import javax.naming.Reference;
-import javax.naming.StringRefAddr;
-import javax.servlet.ServletContext;
-import javax.servlet.SessionTrackingMode;
-import javax.servlet.jsp.JspApplicationContext;
-import javax.servlet.jsp.JspFactory;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
-
 import org.apache.catalina.Cluster;
 import org.apache.catalina.Container;
 import org.apache.catalina.Engine;
@@ -168,6 +127,46 @@ import org.apache.webbeans.config.WebBea
 import org.apache.webbeans.spi.adaptor.ELAdaptor;
 import org.omg.CORBA.ORB;
 
+import javax.ejb.spi.HandleDelegate;
+import javax.el.ELResolver;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import javax.servlet.ServletContext;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.jsp.JspApplicationContext;
+import javax.servlet.jsp.JspFactory;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import static org.apache.tomee.catalina.BackportUtil.getNamingContextListener;
+import static org.apache.tomee.catalina.Contexts.warPath;
+
 /**
  * Web application builder.
  *
@@ -1084,6 +1083,8 @@ public class TomcatWebAppBuilder impleme
     private void startInternal(final StandardContext standardContext) {
         if (isIgnored(standardContext)) return;
 
+        
forceWebAppLoaderToGetAParent(standardContext.getLoader().getClassLoader(), 
standardContext.getParentClassLoader());
+
         final CoreContainerSystem cs = getContainerSystem();
 
         final Assembler a = getAssembler();
@@ -1372,6 +1373,18 @@ public class TomcatWebAppBuilder impleme
         }
     }
 
+    private void forceWebAppLoaderToGetAParent(final ClassLoader classLoader, 
final ClassLoader parent) {
+        if (!LazyStopWebappClassLoader.class.isInstance(classLoader)) {
+            return;
+        }
+
+        // workaround since tomcat doesn't support reload anymore
+        if (Reflections.get(classLoader, "parent") == null) { // then the 
current loader was reloaded and is now broken if we need parent
+            // this algorithm is broken for ears but ears will not be reloaded 
this way normally
+            Reflections.set(classLoader, "parent", parent);
+        }
+    }
+
     private static File rootPath(final File file) {
         if (file.isDirectory() && file.getName().equals("classes") && 
file.getParentFile() != null && 
file.getParentFile().getName().equals("WEB-INF")) {
             return file.getParentFile().getParentFile();

Modified: tomee/tomee/trunk/tomee/tomee-jaxrs/pom.xml
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-jaxrs/pom.xml?rev=1584372&r1=1584371&r2=1584372&view=diff
==============================================================================
--- tomee/tomee/trunk/tomee/tomee-jaxrs/pom.xml (original)
+++ tomee/tomee/trunk/tomee/tomee-jaxrs/pom.xml Thu Apr  3 20:12:57 2014
@@ -82,5 +82,12 @@
       <version>${tomcat.version}</version>
       <scope>provided</scope>
     </dependency>
+
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-coyote</artifactId>
+      <version>${tomcat.version}</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>

Added: 
tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReloadingLoaderTest.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReloadingLoaderTest.java?rev=1584372&view=auto
==============================================================================
--- 
tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReloadingLoaderTest.java
 (added)
+++ 
tomee/tomee/trunk/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReloadingLoaderTest.java
 Thu Apr  3 20:12:57 2014
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.jaxrs;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.openejb.AppContext;
+import org.apache.openejb.BeanContext;
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.apache.openejb.assembler.classic.FacilitiesInfo;
+import org.apache.openejb.assembler.classic.OpenEjbConfiguration;
+import 
org.apache.openejb.assembler.classic.event.AssemblerAfterApplicationCreated;
+import 
org.apache.openejb.assembler.classic.event.AssemblerBeforeApplicationDestroyed;
+import org.apache.openejb.classloader.WebAppEnricher;
+import org.apache.openejb.core.CoreContainerSystem;
+import org.apache.openejb.core.ParentClassLoaderFinder;
+import org.apache.openejb.core.WebContext;
+import org.apache.openejb.core.ivm.naming.IvmContext;
+import org.apache.openejb.core.ivm.naming.IvmJndiFactory;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.cxf.rs.CxfRSService;
+import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.util.reflection.Reflections;
+import org.apache.tomee.catalina.LazyStopWebappClassLoader;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.Properties;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+public class ReloadingLoaderTest {
+    private AppInfo info;
+    private AppContext context;
+    private LazyStopWebappClassLoader loader;
+
+    @BeforeClass
+    @AfterClass
+    public static void resetSystemInstance() {
+        SystemInstance.reset();
+    }
+
+    @Before
+    public void initContext() throws LifecycleException {
+        final OpenEjbConfiguration configuration = new OpenEjbConfiguration();
+        configuration.facilities = new FacilitiesInfo();
+
+        final CoreContainerSystem containerSystem = new 
CoreContainerSystem(new IvmJndiFactory());
+
+        SystemInstance.get().setComponent(OpenEjbConfiguration.class, 
configuration);
+        SystemInstance.get().setComponent(ContainerSystem.class, 
containerSystem);
+        SystemInstance.get().setComponent(WebAppEnricher.class, new 
WebAppEnricher() {
+            @Override
+            public URL[] enrichment(final ClassLoader webappClassLaoder) {
+                return new URL[0];
+            }
+        });
+
+        loader = new 
LazyStopWebappClassLoader(ParentClassLoaderFinder.Helper.get());
+        loader.init();
+        loader.start();
+
+        info = new AppInfo();
+        info.appId = "test";
+        context = new AppContext(info.appId, SystemInstance.get(), loader, new 
IvmContext(), new IvmContext(), true);
+        containerSystem.addAppContext(context);
+
+        final WebContext webDeployment = new WebContext(context);
+        webDeployment.setId(context.getId());
+        webDeployment.setClassLoader(loader);
+        containerSystem.addWebContext(webDeployment);
+    }
+
+    @After
+    public void cleanUp() throws LifecycleException {
+        loader.stop();
+    }
+    @Test
+    public void 
tomcatClassLoaderParentShouldntBeNulAfterAStopStartOtherwiseReloadIsBroken() 
throws Exception {
+        final CxfRSService server = new CxfRSService();
+        try {
+            server.init(new Properties());
+            server.start();
+
+            server.afterApplicationCreated(new 
AssemblerAfterApplicationCreated(info, context, 
Collections.<BeanContext>emptyList()));
+
+            {
+                final ClassLoader beforeLoader = 
SystemInstance.get().getComponent(ContainerSystem.class).getWebContext("test").getClassLoader();
+                assertSame(loader, beforeLoader);
+                assertNotNull(beforeLoader);
+                assertNotNull(Reflections.get(beforeLoader, "parent")); // 
getParent != parent from WebAppClassLoader
+            }
+
+            loader.internalStop();
+
+            server.undeploy(new AssemblerBeforeApplicationDestroyed(info, 
context));
+
+            {
+                final ClassLoader afterLoader = 
SystemInstance.get().getComponent(ContainerSystem.class).getWebContext("test").getClassLoader();
+                assertSame(loader, afterLoader);
+                assertNotNull(afterLoader);
+                assertNull(Reflections.get(afterLoader, "parent"));
+            }
+
+            loader.start();
+            // TomcatWebAppBuilder ill catch start event from StandardContext 
and force a classloader
+            Reflections.set(loader, "parent", 
ParentClassLoaderFinder.Helper.get());
+
+            server.afterApplicationCreated(new 
AssemblerAfterApplicationCreated(info, context, 
Collections.<BeanContext>emptyList()));
+
+            {
+                final ClassLoader afterLoader = 
SystemInstance.get().getComponent(ContainerSystem.class).getWebContext("test").getClassLoader();
+                assertSame(loader, afterLoader);
+                assertNotNull(afterLoader);
+                assertNotNull(Reflections.get(afterLoader, "parent"));
+            }
+
+            server.undeploy(new AssemblerBeforeApplicationDestroyed(info, 
context));
+        } finally {
+            server.stop();
+        }
+    }
+}


Reply via email to