Author: rmannibucau
Date: Thu Mar 14 16:21:58 2013
New Revision: 1456506

URL: http://svn.apache.org/r1456506
Log:
TOMEE-794 adding jars.xml

Added:
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickJarsXmlParser.java
      - copied, changed from r1455467, 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java
    
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Contexts.java
    
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ProvisioningWebappLoader.java
Modified:
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java
    
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java
    
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java?rev=1456506&r1=1456505&r2=1456506&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java
 Thu Mar 14 16:21:58 2013
@@ -19,6 +19,7 @@ package org.apache.openejb;
 import org.apache.openejb.assembler.classic.AppInfo;
 import org.apache.openejb.classloader.ClassLoaderConfigurer;
 import org.apache.openejb.classloader.CompositeClassLoaderConfigurer;
+import org.apache.openejb.config.QuickJarsXmlParser;
 import org.apache.openejb.core.TempClassLoader;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.util.LogCategory;
@@ -308,6 +309,9 @@ public class ClassLoaderUtil {
             }
         }
 
+        final Collection<URL> jarsXmlUrls = QuickJarsXmlParser.parse(new 
File(appId, "META-INF/" + QuickJarsXmlParser.FILE_NAME)).getAdditionalURLs();
+        jarsXmlUrls.addAll(QuickJarsXmlParser.parse(new File(appId, "WEB-INF/" 
+ QuickJarsXmlParser.FILE_NAME)).getAdditionalURLs());
+
         final URL[] urls;
         ClassLoaderConfigurer configurer = 
ClassLoaderUtil.configurer(updatedAppId);
         if (configurer == null) { // try the complete path
@@ -321,11 +325,19 @@ public class ClassLoaderUtil {
                 }
             }
             urlList.addAll(Arrays.asList(configurer.additionalURLs()));
+            urlList.addAll(jarsXmlUrls);
             urls = urlList.toArray(new URL[urlList.size()]);
-        } else {
+        } else if (jarsXmlUrls.isEmpty()) {
             urls = rawUrls;
+        } else {
+            final Collection<URL> urlList = new ArrayList<URL>();
+            urlList.addAll(Arrays.asList(rawUrls));
+            urlList.addAll(jarsXmlUrls);
+            urls = urlList.toArray(new URL[urlList.size()]);
         }
 
+
+
         return new TempClassLoader(createClassLoader(appId, urls, parent));
     }
 
@@ -523,6 +535,9 @@ public class ClassLoaderUtil {
         if (id != null && (id.startsWith("/") || id.startsWith("\\")) && !new 
File(id).exists() && id.length() > 1) {
             id = id.substring(1);
         }
+        if (id == null) {
+            id = "";
+        }
 
         // TODO: see how to manage tomee/openejb prefix
         String key = "tomee.classloader.configurer." + id + ".clazz";

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1456506&r1=1456505&r2=1456506&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 Thu Mar 14 16:21:58 2013
@@ -59,6 +59,7 @@ import org.apache.openejb.classloader.Cl
 import org.apache.openejb.component.ClassLoaderEnricher;
 import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.config.NewLoaderLogic;
+import org.apache.openejb.config.QuickJarsXmlParser;
 import org.apache.openejb.config.TldScanner;
 import org.apache.openejb.core.ConnectorReference;
 import org.apache.openejb.core.CoreContainerSystem;
@@ -1708,6 +1709,14 @@ public class Assembler extends Assembler
             jars.addAll(Arrays.asList(configurer.additionalURLs()));
         }
 
+        final String prefix;
+        if (appInfo.webAppAlone) {
+            prefix = "WEB-INF/";
+        } else {
+            prefix = "META-INF/";
+        }
+        jars.addAll(QuickJarsXmlParser.parse(new File(appInfo.path, prefix + 
QuickJarsXmlParser.FILE_NAME)).getAdditionalURLs());
+
         final URL[] filtered = jars.toArray(new URL[jars.size()]);
 
         if (appInfo.delegateFirst) {

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java?rev=1456506&r1=1456505&r2=1456506&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
 Thu Mar 14 16:21:58 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.openejb.config;
 
+import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.openejb.ClassLoaderUtil;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.api.LocalClient;
@@ -150,7 +151,7 @@ public class DeploymentLoader implements
             }
 
             if (EjbModule.class.equals(moduleClass)) {
-                final URL[] urls = new URL[]{baseUrl};
+                final URL[] urls = new URL[]{ baseUrl };
 
                 SystemInstance.get().fireEvent(new 
BeforeDeploymentEvent(urls));
 
@@ -224,7 +225,7 @@ public class DeploymentLoader implements
 
             if (PersistenceModule.class.equals(moduleClass)) {
                 final String jarLocation = URLs.toFilePath(baseUrl);
-                final ClassLoader classLoader = 
ClassLoaderUtil.createTempClassLoader(jarPath, new URL[]{baseUrl}, 
getOpenEJBClassLoader());
+                final ClassLoader classLoader = 
ClassLoaderUtil.createTempClassLoader(jarPath, new URL[]{ baseUrl }, 
getOpenEJBClassLoader());
 
                 // wrap the EJB Module with an Application Module
                 final AppModule appModule = new AppModule(classLoader, 
jarLocation);
@@ -392,32 +393,19 @@ public class DeploymentLoader implements
 
                 // todo we should also filter URLs here using 
DeploymentsResolver.loadFromClasspath
 
-                for (final Map.Entry<String, URL> entry : files.entrySet()) {
-                    // if (entry.getKey().startsWith("lib/")) continue;// will 
not be scanned since we don't get folder anymore
-                    if (!entry.getKey().matches(".*\\.(jar|war|rar|ear)")) 
continue;
+                createApplicationFromFiles(appId, tmpClassLoader, ejbModules, 
clientModules, resouceModules, webModules, files);
+            }
 
+            final Collection<URL> jarsXmlUrls = QuickJarsXmlParser.parse(new 
File(appDir, "META-INF/" + QuickJarsXmlParser.FILE_NAME)).getAdditionalURLs();
+            final Collection<URL> jarsXmlLib = new ArrayList<URL>();
+            if (!jarsXmlUrls.isEmpty()) {
+                for (final URL url : jarsXmlUrls) {
                     try {
-                        final ClassLoader moduleClassLoader = 
ClassLoaderUtil.createTempClassLoader(appId, new URL[]{entry.getValue()}, 
tmpClassLoader);
-
-                        final Class<? extends DeploymentModule> moduleType = 
discoverModuleType(entry.getValue(), moduleClassLoader, true);
-
-                        if (EjbModule.class.equals(moduleType)) {
-                            ejbModules.put(entry.getKey(), entry.getValue());
-                        } else if (ClientModule.class.equals(moduleType)) {
-                            clientModules.put(entry.getKey(), 
entry.getValue());
-                        } else if (ConnectorModule.class.equals(moduleType)) {
-                            resouceModules.put(entry.getKey(), 
entry.getValue());
-                        } else if (WebModule.class.equals(moduleType)) {
-                            webModules.put(entry.getKey(), entry.getValue());
-                        }
-                    } catch (UnsupportedOperationException e) {
-                        // Ignore it as per the javaee spec EE.8.4.2 section 
1.d.iii
-                        logger.info("Ignoring unknown module type: " + 
entry.getKey());
-                    } catch (UnknownModuleTypeException e) {
-                        // Ignore it as per the javaee spec EE.8.4.2 section 
1.d.iii
-                        logger.info("Ignoring unknown module type: " + 
entry.getKey());
-                    } catch (Exception e) {
-                        throw new OpenEJBException("Unable to determine the 
module type of " + entry.getKey() + ": Exception: " + e.getMessage(), e);
+                        detectAndAddModuleToApplication(appId, tmpClassLoader,
+                                ejbModules, clientModules, resouceModules, 
webModules,
+                                new ImmutablePair<String, 
URL>(URLs.toFile(url).getAbsolutePath(), url));
+                    } catch (final Exception e) {
+                        jarsXmlLib.add(url);
                     }
                 }
             }
@@ -483,6 +471,7 @@ public class DeploymentLoader implements
             classPath.addAll(clientModules.values());
             classPath.addAll(rarLibs.values());
             classPath.addAll(extraLibs);
+            classPath.addAll(jarsXmlLib);
             final URL[] urls = classPath.toArray(new URL[classPath.size()]);
 
             SystemInstance.get().fireEvent(new BeforeDeploymentEvent(urls));
@@ -610,6 +599,41 @@ public class DeploymentLoader implements
         }
     }
 
+    private void createApplicationFromFiles(String appId, ClassLoader 
tmpClassLoader, Map<String, URL> ejbModules, Map<String, URL> clientModules, 
Map<String, URL> resouceModules, Map<String, URL> webModules, HashMap<String, 
URL> files) throws OpenEJBException {
+        for (final Map.Entry<String, URL> entry : files.entrySet()) {
+            // if (entry.getKey().startsWith("lib/")) continue;// will not be 
scanned since we don't get folder anymore
+            if (!entry.getKey().matches(".*\\.(jar|war|rar|ear)")) continue;
+
+            try {
+                detectAndAddModuleToApplication(appId, tmpClassLoader, 
ejbModules, clientModules, resouceModules, webModules, entry);
+            } catch (UnsupportedOperationException e) {
+                // Ignore it as per the javaee spec EE.8.4.2 section 1.d.iii
+                logger.info("Ignoring unknown module type: " + entry.getKey());
+            } catch (UnknownModuleTypeException e) {
+                // Ignore it as per the javaee spec EE.8.4.2 section 1.d.iii
+                logger.info("Ignoring unknown module type: " + entry.getKey());
+            } catch (Exception e) {
+                throw new OpenEJBException("Unable to determine the module 
type of " + entry.getKey() + ": Exception: " + e.getMessage(), e);
+            }
+        }
+    }
+
+    private void detectAndAddModuleToApplication(String appId, ClassLoader 
tmpClassLoader, Map<String, URL> ejbModules, Map<String, URL> clientModules, 
Map<String, URL> resouceModules, Map<String, URL> webModules, Map.Entry<String, 
URL> entry) throws IOException, UnknownModuleTypeException {
+        final ClassLoader moduleClassLoader = 
ClassLoaderUtil.createTempClassLoader(appId, new URL[]{entry.getValue()}, 
tmpClassLoader);
+
+        final Class<? extends DeploymentModule> moduleType = 
discoverModuleType(entry.getValue(), moduleClassLoader, true);
+
+        if (EjbModule.class.equals(moduleType)) {
+            ejbModules.put(entry.getKey(), entry.getValue());
+        } else if (ClientModule.class.equals(moduleType)) {
+            clientModules.put(entry.getKey(), entry.getValue());
+        } else if (ConnectorModule.class.equals(moduleType)) {
+            resouceModules.put(entry.getKey(), entry.getValue());
+        } else if (WebModule.class.equals(moduleType)) {
+            webModules.put(entry.getKey(), entry.getValue());
+        }
+    }
+
     protected ClientModule createClientModule(final URL clientUrl, final 
String absolutePath, final ClassLoader appClassLoader, final String moduleName) 
throws OpenEJBException {
         return createClientModule(clientUrl, absolutePath, appClassLoader, 
moduleName, true);
     }
@@ -857,6 +881,8 @@ public class DeploymentLoader implements
             webUrls.addAll(parser.getAdditionalURLs());
         }
 
+        webUrls.addAll(QuickJarsXmlParser.parse(new File(warFile, "WEB-INF/" + 
QuickJarsXmlParser.FILE_NAME)).getAdditionalURLs());
+
         final URL[] webUrlsArray = webUrls.toArray(new URL[webUrls.size()]);
 
         // in TomEE this is done in init hook since we don't manage tomee 
webapp classloader
@@ -1275,6 +1301,7 @@ public class DeploymentLoader implements
         // create the class loader
         final List<URL> classPath = new ArrayList<URL>();
         classPath.addAll(rarLibs.values());
+        classPath.addAll(QuickJarsXmlParser.parse(new File(rarFile, 
"META-INF/" + QuickJarsXmlParser.FILE_NAME)).getAdditionalURLs());
         final URL[] urls = classPath.toArray(new URL[classPath.size()]);
         final ClassLoader appClassLoader = 
ClassLoaderUtil.createTempClassLoader(appId, urls, parentClassLoader);
 

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java?rev=1456506&r1=1456505&r2=1456506&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java
 Thu Mar 14 16:21:58 2013
@@ -46,7 +46,8 @@ public class QuickContextXmlParser exten
                              final String qName, final Attributes attributes) 
throws SAXException {
         if ("Loader".equalsIgnoreCase(localName)) {
             final String className = attributes.getValue("className");
-            if 
("org.apache.catalina.loader.VirtualWebappLoader".equals(className)) {
+            if 
("org.apache.catalina.loader.VirtualWebappLoader".equals(className)
+                    || 
"org.apache.tomee.catalina.ProvisioningWebappLoader".equals(className)) {
                 virtualClasspath = attributes.getValue("virtualClasspath");
             } // else ?
         }

Copied: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickJarsXmlParser.java
 (from r1455467, 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java)
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickJarsXmlParser.java?p2=tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickJarsXmlParser.java&p1=tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java&r1=1455467&r2=1456506&rev=1456506&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickContextXmlParser.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/QuickJarsXmlParser.java
 Thu Mar 14 16:21:58 2013
@@ -16,6 +16,9 @@
  */
 package org.apache.openejb.config;
 
+import org.apache.openejb.loader.ProvisioningUtil;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
@@ -25,6 +28,7 @@ import javax.xml.parsers.SAXParserFactor
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedHashSet;
@@ -32,85 +36,44 @@ import java.util.Locale;
 import java.util.Set;
 import java.util.StringTokenizer;
 
-public class QuickContextXmlParser extends DefaultHandler {
+public class QuickJarsXmlParser extends DefaultHandler {
+    public static final String FILE_NAME = "jars.xml";
+
     private static final SAXParserFactory FACTORY = 
SAXParserFactory.newInstance();
     static {
         FACTORY.setNamespaceAware(true);
         FACTORY.setValidating(false);
     }
 
-    private String virtualClasspath = "";
+    private final Collection<URL> deps = new ArrayList<URL>();
 
     @Override
     public void startElement(final String uri, final String localName,
                              final String qName, final Attributes attributes) 
throws SAXException {
-        if ("Loader".equalsIgnoreCase(localName)) {
-            final String className = attributes.getValue("className");
-            if 
("org.apache.catalina.loader.VirtualWebappLoader".equals(className)) {
-                virtualClasspath = attributes.getValue("virtualClasspath");
-            } // else ?
+        if ("jar".equalsIgnoreCase(localName)) {
+            final String value = attributes.getValue("path");
+            if (value != null) {
+                try {
+                    deps.add(new 
File(ProvisioningUtil.realLocation(value)).toURI().toURL());
+                } catch (final MalformedURLException e) {
+                    Logger.getInstance(LogCategory.OPENEJB, 
QuickJarsXmlParser.class).error("Can't find " + value);
+                }
+            }
         }
     }
 
     public Collection<URL> getAdditionalURLs() {
-        final StringTokenizer tkn = new StringTokenizer(virtualClasspath, ";");
-        final Set<URL> set = new LinkedHashSet<URL>();
-        while (tkn.hasMoreTokens()) {
-            String token = tkn.nextToken().trim();
-            if (token.isEmpty()) {
-                continue;
-            }
-
-            if (token.endsWith("*.jar")) {
-                token = token.substring(0, token.length() - "*.jar".length());
-
-                final File directory = new File(token);
-                if (!directory.isDirectory()) {
-                    continue;
-                }
-
-                final String filenames[] = directory.list();
-                Arrays.sort(filenames);
-
-                for (final String rawFilename : filenames) {
-                    final String filename = 
rawFilename.toLowerCase(Locale.ENGLISH);
-                    if (!filename.endsWith(".jar")) {
-                        continue;
-                    }
-
-                    final File file = new File(directory, rawFilename);
-                    if (!file.isFile()) {
-                        continue;
-                    }
-
-                    try {
-                        set.add(file.toURI().toURL());
-                    } catch (MalformedURLException e) {
-                        // no-op
-                    }
-                }
-            } else {
-                // single file or directory
-                final File file = new File(token);
-                if (!file.exists()) {
-                    continue;
-                }
+        return deps;
+    }
 
-                try {
-                    set.add(file.toURI().toURL());
-                } catch (MalformedURLException e) {
-                    // no-op
-                }
-            }
+    public static QuickJarsXmlParser parse(final File contextXml) {
+        final QuickJarsXmlParser handler = new QuickJarsXmlParser();
+        if (!contextXml.exists()) {
+            return handler;
         }
-        return set;
-    }
 
-    public static QuickContextXmlParser parse(final File contextXml) {
-        final QuickContextXmlParser handler = new QuickContextXmlParser();
         try {
-            final SAXParser parser = FACTORY.newSAXParser();
-            parser.parse(contextXml, handler);
+            FACTORY.newSAXParser().parse(contextXml, handler);
         } catch (final Exception e) {
             // no-op: not parseable so ignoring
         }

Added: 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Contexts.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Contexts.java?rev=1456506&view=auto
==============================================================================
--- 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Contexts.java
 (added)
+++ 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Contexts.java
 Thu Mar 14 16:21:58 2013
@@ -0,0 +1,125 @@
+/*
+ * 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.catalina;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
+import org.apache.catalina.Host;
+import org.apache.catalina.core.StandardEngine;
+import org.apache.catalina.core.StandardHost;
+
+import java.io.File;
+
+public class Contexts {
+    public static File warPath(final Context standardContext) {
+        final File file = realWarPath(standardContext);
+        if (file == null) {
+            return file;
+        }
+
+        final String name = file.getName();
+        if (!file.isDirectory() && name.endsWith(".war")) {
+            final File extracted = new File(file.getParentFile(), 
name.substring(0, name.length() - ".war".length()));
+            if (extracted.exists()) {
+                return extracted;
+            }
+        }
+        return file;
+    }
+
+    public static File realWarPath(final Context standardContext) {
+        if (standardContext == null) {
+            return null;
+        }
+
+        File docBase;
+        Container container = standardContext;
+        while (container != null) {
+            if (container instanceof Host) {
+                break;
+            }
+            container = container.getParent();
+        }
+
+        File file = new File(standardContext.getDocBase());
+        if (!file.isAbsolute()) {
+            if (container == null) {
+                docBase = new File(engineBase(standardContext), 
standardContext.getDocBase());
+            } else {
+                final String appBase = ((Host) container).getAppBase();
+                file = new File(appBase);
+                if (!file.isAbsolute()) {
+                    file = new File(engineBase(standardContext), appBase);
+                }
+                docBase = new File(file, standardContext.getDocBase());
+            }
+        } else {
+            docBase = file;
+        }
+
+        if (!docBase.exists()) { // for old compatibility, will be removed soon
+            return oldRealWarPath(standardContext);
+        }
+
+        final String name = docBase.getName();
+        if (name.endsWith(".war")) {
+            final File extracted = new File(docBase.getParentFile(), 
name.substring(0, name.length() - ".war".length()));
+            if (extracted.exists()) {
+                return extracted;
+            }
+        }
+
+        return docBase;
+    }
+
+    private static File engineBase(final Context standardContext) {
+        String base=System.getProperty(Globals.CATALINA_BASE_PROP);
+        if( base == null ) {
+            final StandardEngine eng = (StandardEngine) 
standardContext.getParent().getParent();
+            base = eng.getBaseDir();
+        }
+        return new File(base);
+    }
+
+    @Deprecated
+    private static File oldRealWarPath(final Context standardContext) {
+        String doc = standardContext.getDocBase();
+        // handle ROOT case
+        if (doc == null || doc.length() == 0) {
+            doc = "ROOT";
+        }
+
+        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
+    }
+}

Modified: 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java?rev=1456506&r1=1456505&r2=1456506&view=diff
==============================================================================
--- 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java
 (original)
+++ 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java
 Thu Mar 14 16:21:58 2013
@@ -21,18 +21,7 @@ import org.apache.catalina.LifecycleExce
 import org.apache.catalina.loader.VirtualWebappLoader;
 
 public class LazyStopWebappLoader extends VirtualWebappLoader {
-    private static String currentAppId = null;
-
-    private Context standardContext = null;
-
-    public LazyStopWebappLoader(final Context ctx) {
-        super(ctx.getParentClassLoader());
-        standardContext = ctx;
-    }
-
-    public LazyStopWebappLoader() {
-        // no-op
-    }
+    private static final ThreadLocal<String> currentAppId = new 
ThreadLocal<String>();
 
     @Override
     public void backgroundProcess() {
@@ -52,27 +41,27 @@ public class LazyStopWebappLoader extend
 
     @Override
     protected synchronized void startInternal() throws LifecycleException {
-        currentAppId = standardContext.getName(); // needed by classloader 
instantiated by next line
+        currentAppId.set(getContainer().getName()); // needed by classloader 
instantiated by next line
         try {
             super.startInternal();
         } finally {
-            currentAppId = null;
-        }
-
-        if (getClassLoader() instanceof LazyStopWebappClassLoader) {
-            ((LazyStopWebappClassLoader) 
getClassLoader()).setRelatedContext(standardContext);
+            currentAppId.remove();
         }
     }
 
     public static String getCurrentAppId() {
-        return currentAppId;
+        final String id = currentAppId.get();
+        if (id == null) {
+            currentAppId.remove();
+        }
+        return id;
     }
 
     public String getAppId() {
-        if (standardContext == null) {
+        if (getContainer() == null) {
             return null;
         }
-        return standardContext.getName();
+        return getContainer().getName();
     }
 
     @Override

Added: 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ProvisioningWebappLoader.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ProvisioningWebappLoader.java?rev=1456506&view=auto
==============================================================================
--- 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ProvisioningWebappLoader.java
 (added)
+++ 
tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ProvisioningWebappLoader.java
 Thu Mar 14 16:21:58 2013
@@ -0,0 +1,78 @@
+/**
+ *
+ * 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.catalina;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.openejb.config.QuickJarsXmlParser;
+import org.apache.openejb.loader.ProvisioningUtil;
+import org.apache.openejb.util.URLs;
+import org.apache.openejb.util.reflection.Reflections;
+
+import java.io.File;
+import java.net.URL;
+
+/**
+ * Usage example in META-INF/context.xml
+ *
+
+ <Context antiJARLocking="true" >
+     <Loader
+         className="org.apache.tomee.catalina.ProvisioningWebappLoader"
+         searchExternalFirst="true"
+         
virtualClasspath="mvn:commons-el:commons-el:1.0;mvn:commons-el:commons-el:1.0"
+         searchVirtualFirst="true"
+     />
+ </Context>
+
+ *
+ */
+public class ProvisioningWebappLoader extends LazyStopWebappLoader {
+    @Override
+    protected void startInternal() throws LifecycleException {
+        // standard tomcat part
+        final StringBuilder builder = new StringBuilder();
+        final String classpath = String.class.cast(Reflections.get(this, 
"virtualClasspath"));
+        if (!classpath.isEmpty()) {
+            for (final String s : String.class.cast(classpath).split(";")) {
+                builder.append(ProvisioningUtil.realLocation(s)).append(";");
+            }
+        }
+
+        // WEB-INF/jars.xml
+        if (Context.class.isInstance(getContainer())) {
+            final File war = 
Contexts.warPath(Context.class.cast(getContainer()));
+            final File jarsXml = new File(war, "WEB-INF/" + 
QuickJarsXmlParser.FILE_NAME);
+            if (jarsXml.exists()) {
+                final QuickJarsXmlParser parser = 
QuickJarsXmlParser.parse(jarsXml);
+                for (final URL url : parser.getAdditionalURLs()) {
+                    builder.append(URLs.toFile(url)).append(";"); // 
provisiningutil already called so simply decode url
+                }
+            }
+        }
+
+        // clean up builder and set classpath to delegate to parent init
+        String cp = builder.toString();
+        if (cp.endsWith(";")) {
+            cp = cp.substring(0, cp.length() - 1);
+        }
+        Reflections.set(this, "virtualClasspath", cp);
+
+        super.startInternal();
+    }
+}

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=1456506&r1=1456505&r2=1456506&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 Mar 14 16:21:58 2013
@@ -19,7 +19,6 @@ package org.apache.tomee.catalina;
 import org.apache.catalina.Cluster;
 import org.apache.catalina.Container;
 import org.apache.catalina.Engine;
-import org.apache.catalina.Globals;
 import org.apache.catalina.Host;
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.LifecycleListener;
@@ -34,7 +33,6 @@ import org.apache.catalina.Wrapper;
 import org.apache.catalina.core.ContainerBase;
 import org.apache.catalina.core.NamingContextListener;
 import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.core.StandardEngine;
 import org.apache.catalina.core.StandardHost;
 import org.apache.catalina.core.StandardServer;
 import org.apache.catalina.core.StandardWrapper;
@@ -666,7 +664,7 @@ public class TomcatWebAppBuilder impleme
                 final StandardContext standardContext = 
contextInfo.standardContext;
 
                 undeploy(standardContext, contextInfo);
-                final File extracted = warPath(standardContext);
+                final File extracted = Contexts.warPath(standardContext);
                 if (isExtracted(extracted)) {
                     deleteDir(extracted);
                 }
@@ -732,7 +730,7 @@ public class TomcatWebAppBuilder impleme
 
         initJ2EEInfo(standardContext);
 
-        File warFile = warPath(standardContext);
+        File warFile = Contexts.warPath(standardContext);
         if (!warFile.isDirectory()) {
             try {
                 warFile = DeploymentLoader.unpack(warFile);
@@ -834,99 +832,6 @@ public class TomcatWebAppBuilder impleme
         return path;
     }
 
-    private static File warPath(final StandardContext standardContext) {
-        final File file = realWarPath(standardContext);
-        if (file == null) {
-            return file;
-        }
-
-        final String name = file.getName();
-        if (!file.isDirectory() && name.endsWith(".war")) {
-            final File extracted = new File(file.getParentFile(), 
name.substring(0, name.length() - ".war".length()));
-            if (extracted.exists()) {
-                return extracted;
-            }
-        }
-        return file;
-    }
-
-    private static File realWarPath(final StandardContext standardContext) {
-        File docBase;
-        Container container = standardContext;
-        while (container != null) {
-            if (container instanceof Host) {
-                break;
-            }
-            container = container.getParent();
-        }
-
-        File file = new File(standardContext.getDocBase());
-        if (!file.isAbsolute()) {
-            if (container == null) {
-                docBase = new File(engineBase(standardContext), 
standardContext.getDocBase());
-            } else {
-                final String appBase = ((Host) container).getAppBase();
-                file = new File(appBase);
-                if (!file.isAbsolute()) {
-                    file = new File(engineBase(standardContext), appBase);
-                }
-                docBase = new File(file, standardContext.getDocBase());
-            }
-        } else {
-            docBase = file;
-        }
-
-        if (!docBase.exists()) { // for old compatibility, will be removed soon
-            return oldRealWarPath(standardContext);
-        }
-
-        final String name = docBase.getName();
-        if (name.endsWith(".war")) {
-            final File extracted = new File(docBase.getParentFile(), 
name.substring(0, name.length() - ".war".length()));
-            if (extracted.exists()) {
-                return extracted;
-            }
-        }
-
-        return docBase;
-    }
-
-    private static File engineBase(final StandardContext standardContext) {
-        String base=System.getProperty(Globals.CATALINA_BASE_PROP);
-        if( base == null ) {
-            final StandardEngine eng = (StandardEngine) 
standardContext.getParent().getParent();
-            base = eng.getBaseDir();
-        }
-        return new File(base);
-    }
-
-    @Deprecated
-    private static File oldRealWarPath(final StandardContext standardContext) {
-        String doc = standardContext.getDocBase();
-        // handle ROOT case
-        if (doc == null || doc.length() == 0) {
-            doc = "ROOT";
-        }
-
-        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 ContextInfo getContextInfo(final String appName) {
         ContextInfo info = null;
         for (Map.Entry<String, ContextInfo> current : infos.entrySet()) {
@@ -1020,8 +925,6 @@ public class TomcatWebAppBuilder impleme
             }
         }
         initContextLoader(standardContext);
-
-
     }
 
     private void initContextLoader(final StandardContext standardContext) {
@@ -1036,9 +939,14 @@ public class TomcatWebAppBuilder impleme
             return;
         }
 
+        if (standardContextLoader != null && 
LazyStopWebappLoader.class.isInstance(standardContextLoader)) {
+            standardContextLoader.setContainer(standardContext);
+            return; // no need to replace the loader
+        }
+
         // we just want to wrap it to lazy stop it (afterstop)
         // to avoid classnotfound in @PreDestoy or destroyApplication()
-        final VirtualWebappLoader loader = new 
LazyStopWebappLoader(standardContext);
+        final VirtualWebappLoader loader = new ProvisioningWebappLoader();
         loader.setDelegate(standardContext.getDelegate());
         loader.setLoaderClass(LazyStopWebappClassLoader.class.getName());
 
@@ -1759,7 +1667,7 @@ public class TomcatWebAppBuilder impleme
                 final StandardContext standardContext = 
contextInfo.standardContext;
                 final HostConfig deployer = contextInfo.deployer;
                 deployer.unmanageApp(standardContext.getPath());
-                final File realPath = warPath(standardContext);
+                final File realPath = Contexts.warPath(standardContext);
                 if (realPath != null) {
                     deleteDir(realPath);
                 }
@@ -1933,7 +1841,7 @@ public class TomcatWebAppBuilder impleme
         final TomcatDeploymentLoader tomcatDeploymentLoader = new 
TomcatDeploymentLoader(standardContext, id);
         final AppModule appModule;
         try {
-            appModule = tomcatDeploymentLoader.load(warPath(standardContext));
+            appModule = 
tomcatDeploymentLoader.load(Contexts.warPath(standardContext));
         } catch (OpenEJBException e) {
             throw new TomEERuntimeException(e);
         }


Reply via email to