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 2012/07/14 00:12:36 UTC

svn commit: r1361419 - in /openejb/trunk/openejb: container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ container/openejb-core/src/main/java/org/apache/openejb/config/ container/openejb-core/src/main/java/org/apache/openejb/config/...

Author: rmannibucau
Date: Fri Jul 13 22:12:35 2012
New Revision: 1361419

URL: http://svn.apache.org/viewvc?rev=1361419&view=rev
Log:
TOMEE-280 deploy time enhancement - jars

Modified:
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/event/BeforeDeploymentEvent.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/JarCreator.java
    openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java?rev=1361419&r1=1361418&r2=1361419&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java Fri Jul 13 22:12:35 2012
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -80,6 +81,7 @@ public class DeployTimeEnhancer {
         // find persistence.xml
         final Map<String, List<String>> classesByPXml = new HashMap<String, List<String>>();
         final Filter filter = new AlreadyEnhancedFilter();
+        final List<URL> usedUrls = new ArrayList<URL>(); // for fake classloader
         for (URL url : event.getUrls()) {
             final File file = URLs.toFile(url);
             if (filter.accept(file.getName())) {
@@ -88,6 +90,8 @@ public class DeployTimeEnhancer {
                     if (pXmls != null) {
                         feed(classesByPXml, pXmls);
                     }
+
+                    usedUrls.add(url);
                 } else if (file.getName().endsWith(".jar")) {
                     try {
                         final JarFile jar = new JarFile(file);
@@ -96,47 +100,64 @@ public class DeployTimeEnhancer {
                             final String path = file.getAbsolutePath();
                             final File unpacked = new File(path.substring(0, path.length() - 4) + TMP_ENHANCEMENT_SUFFIX);
                             JarExtractor.extract(file, unpacked);
+
+                            // replace jar by folder url since otherwise enhancement doesn't work
+                            usedUrls.add(unpacked.toURI().toURL());
+
                             feed(classesByPXml, new File(unpacked, META_INF_PERSISTENCE_XML).getAbsolutePath());
                         }
                     } catch (IOException e) {
                         // ignored
                     }
                 }
+            } else {
+                usedUrls.add(url);
             }
         }
 
         // enhancement
-        for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) {
-            final Properties opts = new Properties();
-            opts.setProperty(PROPERTIES_FILE_PROP, entry.getKey());
 
-            final Object optsArg;
-            try {
-                optsArg = optionsConstructor.newInstance(opts);
-            } catch (Exception e) {
-                LOGGER.debug("can't create options for enhancing");
-                return;
-            }
+        final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        final ClassLoader fakeClassLoader = new URLClassLoader(usedUrls.toArray(new URL[usedUrls.size()]), event.getParentClassLoader());
 
-            LOGGER.info("enhancing url(s): " + Arrays.asList(event.getUrls()));
-            try {
-                enhancerMethod.invoke(null, toFilePaths(entry.getValue()), optsArg);
-            } catch (Exception e) {
-                LOGGER.warning("can't enhanced at deploy-time entities", e);
+        Thread.currentThread().setContextClassLoader(fakeClassLoader);
+        try {
+            for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) {
+                final Properties opts = new Properties();
+                opts.setProperty(PROPERTIES_FILE_PROP, entry.getKey());
+
+                final Object optsArg;
+                try {
+                    optsArg = optionsConstructor.newInstance(opts);
+                } catch (Exception e) {
+                    LOGGER.debug("can't create options for enhancing");
+                    return;
+                }
+
+                LOGGER.info("enhancing url(s): " + Arrays.asList(event.getUrls()));
+                try {
+                    enhancerMethod.invoke(null, toFilePaths(entry.getValue()), optsArg);
+                } catch (Exception e) {
+                    LOGGER.warning("can't enhanced at deploy-time entities", e);
+                }
             }
+        } finally {
+            Thread.currentThread().setContextClassLoader(tccl);
+            usedUrls.clear();
         }
 
         // clean up extracted jars
         for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) {
             final List<String> values = entry.getValue();
             for (String rawPath : values) {
-                if (rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX)) {
-                    final String path = rawPath.substring(0, rawPath.length() - TMP_ENHANCEMENT_SUFFIX.length());
-                    final File dir = new File(path);
-                    final File file = new File(path + ".jar");
+                if (rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX + "/") || rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX)) {
+                    final File dir = new File(rawPath);
+                    final File file = new File(rawPath.substring(0, rawPath.length() - TMP_ENHANCEMENT_SUFFIX.length() - 1) + ".jar");
                     if (file.exists()) {
+                        String name = dir.getName();
+                        name = name.substring(0, name.length() - TMP_ENHANCEMENT_SUFFIX.length()) + JAR_ENHANCEMENT_SUFFIX + ".jar";
                         try {
-                            JarCreator.jarDir(dir, new File(dir.getParentFile(), dir.getName() + JAR_ENHANCEMENT_SUFFIX + ".jar"));
+                            JarCreator.jarDir(dir, new File(dir.getParentFile(), name));
                             Files.delete(file); // don't delete if any exception is thrown
                         } catch (IOException e) {
                             LOGGER.error("can't repackage enhanced jar file " + file.getName());
@@ -183,7 +204,7 @@ public class DeployTimeEnhancer {
 
     private String getWarPersistenceXml(final URL url) {
         final File dir = URLs.toFile(url);
-        if (dir.isDirectory() && dir.getAbsolutePath().endsWith("/WEB-INF/classes")) {
+        if (dir.isDirectory() && (dir.getAbsolutePath().endsWith("/WEB-INF/classes") || dir.getAbsolutePath().endsWith("/WEB-INF/classes/"))) {
             final File pXmlStd = new File(dir.getParentFile(), "persistence.xml");
             if (pXmlStd.exists()) {
                 return  pXmlStd.getAbsolutePath();
@@ -221,7 +242,7 @@ public class DeployTimeEnhancer {
         @Override
         public boolean accept(final File file) {
             boolean isClass = file.getName().endsWith(CLASS_EXT);
-            if (DEFAULT_EXCLUDE.equals(EXCLUDE_PATTERN) && DEFAULT_INCLUDE.equals(INCLUDE_PATTERN)) {
+            if (DEFAULT_EXCLUDE.equals(EXCLUDE_PATTERN.pattern()) && DEFAULT_INCLUDE.equals(INCLUDE_PATTERN.pattern())) {
                 return isClass;
             }
 

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java?rev=1361419&r1=1361418&r2=1361419&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java Fri Jul 13 22:12:35 2012
@@ -737,7 +737,12 @@ public class DeploymentLoader implements
         // determine war class path
         final URL[] webUrls = getWebappUrls(warFile);
 
-        SystemInstance.get().fireEvent(new BeforeDeploymentEvent(webUrls));
+        // in TomEE this is done in init hook since we don't manage tomee webapp classloader
+        // so here is not the best idea for tomee
+        // if we want to manage it in a generic way
+        // simply add a boolean shared between tomcat and openejb world
+        // to know if we should fire it or not
+        SystemInstance.get().fireEvent(new BeforeDeploymentEvent(webUrls, parentClassLoader));
 
         final ClassLoader warClassLoader = ClassLoaderUtil.createTempClassLoader(appId, webUrls, parentClassLoader);
 
@@ -1515,7 +1520,7 @@ public class DeploymentLoader implements
         return cls;
     }
 
-    protected static File unpack(final File jarFile) throws OpenEJBException {
+    public static File unpack(final File jarFile) throws OpenEJBException {
         if (jarFile.isDirectory()) {
             return jarFile;
         }

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/event/BeforeDeploymentEvent.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/event/BeforeDeploymentEvent.java?rev=1361419&r1=1361418&r2=1361419&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/event/BeforeDeploymentEvent.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/event/BeforeDeploymentEvent.java Fri Jul 13 22:12:35 2012
@@ -8,15 +8,28 @@ import java.util.Arrays;
 @Event
 public class BeforeDeploymentEvent {
     private final URL[] urls;
+    private final ClassLoader parentClassLoader;
 
     public BeforeDeploymentEvent(final URL[] files) {
+        this(files, null);
+    }
+
+    public BeforeDeploymentEvent(final URL[] files, final ClassLoader parent) {
         urls = files;
+        parentClassLoader = parent;
     }
 
     public URL[] getUrls() {
         return urls;
     }
 
+    public ClassLoader getParentClassLoader() {
+        if (parentClassLoader != null) {
+            return parentClassLoader;
+        }
+        return getClass().getClassLoader();
+    }
+
     @Override
     public String toString() {
         return "BeforeDeploymentEvent{" +

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/JarCreator.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/JarCreator.java?rev=1361419&r1=1361418&r2=1361419&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/JarCreator.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/JarCreator.java Fri Jul 13 22:12:35 2012
@@ -19,23 +19,29 @@ public final class JarCreator {
     public static void jarDir(final File dir, final File zipName) throws IOException, IllegalArgumentException {
         final String[] entries = dir.list();
         final JarOutputStream out = new JarOutputStream(new FileOutputStream(zipName));
+
+        String prefix = dir.getAbsolutePath();
+        if (!prefix.endsWith(File.separator)) {
+            prefix += File.separator;
+        }
+
         for (String entry : entries) {
             File f = new File(dir, entry);
-            jarFile(out, f);
+            jarFile(out, f, prefix);
         }
         IO.close(out);
     }
 
-    private static void jarFile(final JarOutputStream out, final File f) throws IOException {
+    private static void jarFile(final JarOutputStream out, final File f, final String prefix) throws IOException {
         if (f.isDirectory()) {
             for (File child : f.listFiles()) {
-                jarFile(out, child);
+                jarFile(out, child, prefix);
             }
         } else {
             final byte[] buffer = new byte[BUFFER_SIZE];
             int bytesRead;
 
-            final String path = f.getPath();
+            final String path = f.getPath().replace(prefix, "");
 
             final FileInputStream in = new FileInputStream(f);
             final JarEntry entry = new JarEntry(path);

Modified: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java?rev=1361419&r1=1361418&r2=1361419&view=diff
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java (original)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java Fri Jul 13 22:12:35 2012
@@ -61,6 +61,7 @@ import org.apache.openejb.config.AppModu
 import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.config.DeploymentLoader;
 import org.apache.openejb.config.WebModule;
+import org.apache.openejb.config.event.BeforeDeploymentEvent;
 import org.apache.openejb.core.CoreContainerSystem;
 import org.apache.openejb.core.WebContext;
 import org.apache.openejb.core.ivm.naming.SystemComponentReference;
@@ -517,6 +518,19 @@ public class TomcatWebAppBuilder impleme
         // just adding a carriage return to get logs more readable
         logger.info("-------------------------\nTomcatWebAppBuilder.init " + standardContext.getPath());
 
+        File warFile = warPath(standardContext);
+        if (!warFile.isDirectory()) {
+            try {
+                warFile = DeploymentLoader.unpack(warFile);
+            } catch (OpenEJBException e) {
+                logger.error("can't unpack '" + warFile.getAbsolutePath() + "'");
+            }
+        }
+
+        if (warFile.exists()) {
+            SystemInstance.get().fireEvent(new BeforeDeploymentEvent(DeploymentLoader.getWebappUrls(warFile)));
+        }
+
         standardContext.setCrossContext(SystemInstance.get().getOptions().get(OPENEJB_CROSSCONTEXT_PROPERTY, false));
         standardContext.setNamingResources(new OpenEJBNamingResource());
 
@@ -569,6 +583,25 @@ public class TomcatWebAppBuilder impleme
         standardContext.addContainerListener(new TomEEContainerListener());
     }
 
+    private static File warPath(final StandardContext standardContext) {
+        final String doc = standardContext.getDocBase();
+        File war = new File(doc);
+        if (war.exists()) {
+            return war;
+        }
+        final StandardHost host = (StandardHost) standardContext.getParent();
+        final String base = host.getAppBase();
+        war = new File(base, doc);
+        if (war.exists()) {
+            return war;
+        }
+        war = new File(new File(System.getProperty("catalina.home"), base), doc);
+        if (war.exists()) {
+            return war;
+        }
+        return new File(new File(System.getProperty("catalina.base"), base), doc); // shouldn't occur
+    }
+
     public class StandardContextInfo {
 
         private final StandardContext standardContext;