Author: rmannibucau
Date: Tue Oct 16 16:08:54 2012
New Revision: 1398867

URL: http://svn.apache.org/viewvc?rev=1398867&view=rev
Log:
TOMEE-473 customization of classloader (+ and -) + XBean 3.12

Added:
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/ClassLoaderConfigurer.java
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/DefaultClassLoaderConfigurer.java
Modified:
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    openejb/trunk/openejb/osgi/openejb-core-osgi/pom.xml
    openejb/trunk/openejb/pom.xml
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.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/ClassLoaderUtil.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java?rev=1398867&r1=1398866&r2=1398867&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/ClassLoaderUtil.java
 Tue Oct 16 16:08:54 2012
@@ -16,11 +16,14 @@
  */
 package org.apache.openejb;
 
+import org.apache.openejb.classloader.ClassLoaderConfigurer;
 import org.apache.openejb.core.TempClassLoader;
+import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.UrlCache;
 import org.apache.openejb.util.classloader.URLClassLoaderFirst;
+import org.apache.xbean.recipe.ObjectRecipe;
 
 import java.beans.Introspector;
 import java.io.File;
@@ -33,7 +36,15 @@ import java.net.URL;
 import java.net.URLClassLoader;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
 import java.util.zip.ZipFile;
 
 /**
@@ -474,4 +485,41 @@ public class ClassLoaderUtil {
     public static String resourceName(final String s) {
         return s.replace(".", "/") + ".class";
     }
+
+    public static ClassLoaderConfigurer configurer(final String rawId) {
+        String id = rawId;
+        if (id != null && id.startsWith("/") && !new File(id).exists() && 
id.length() > 1) {
+            id = id.substring(1);
+        }
+
+        String key = "tomee.classloader.configurer." + id + ".clazz";
+        String impl = SystemInstance.get().getProperty(key);
+        if (impl == null) {
+            key = "tomee.classloader.configurer.clazz";
+            impl = SystemInstance.get().getProperty(key);
+        }
+        if (impl != null) {
+            key = key.substring(0, key.length() - "clazz".length());
+
+            try {
+                final ObjectRecipe recipe = new ObjectRecipe(impl);
+                for (Map.Entry<Object, Object> entry : 
SystemInstance.get().getProperties().entrySet()) {
+                    String entryKey = entry.getKey().toString();
+                    if (entryKey.startsWith(key)) {String newKey = 
entryKey.substring(key.length());if (!"clazz".equals(newKey))
+                        recipe.setProperty(newKey, entry.getValue());
+                    }
+                }
+
+                final Object instance = recipe.create();
+                if (instance instanceof ClassLoaderConfigurer) {
+                    return (ClassLoaderConfigurer) instance;
+                } else {
+                    logger.error(impl + " is not a classlaoder configurer, 
using default behavior");
+                }
+            } catch (Exception e) {
+                logger.error("Can't create classloader configurer " + impl + 
", using default behavior");
+            }
+        }
+        return null;
+    }
 }

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1398867&r1=1398866&r2=1398867&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 Tue Oct 16 16:08:54 2012
@@ -51,6 +51,7 @@ import org.apache.openejb.cdi.ManagedSec
 import org.apache.openejb.cdi.OpenEJBTransactionService;
 import org.apache.openejb.cdi.OptimizedLoaderService;
 import org.apache.openejb.cdi.ThreadSingletonServiceImpl;
+import org.apache.openejb.classloader.ClassLoaderConfigurer;
 import org.apache.openejb.component.ClassLoaderEnricher;
 import org.apache.openejb.core.ConnectorReference;
 import org.apache.openejb.core.CoreContainerSystem;
@@ -1484,10 +1485,23 @@ public class Assembler extends Assembler
             parent = parentFinder.getParentClassLoader(parent);
         }
 
+        final ClassLoaderConfigurer configurer = 
ClassLoaderUtil.configurer(appInfo.appId);
+        if (configurer != null) {
+            final Iterator<URL> it = jars.iterator();
+            while (it.hasNext()) {
+                if (!configurer.accept(it.next())) {
+                    it.remove();
+                }
+            }
+            jars.addAll(Arrays.asList(configurer.additionalURLs()));
+        }
+
+        final URL[] filtered = jars.toArray(new URL[jars.size()]);
+
         if (appInfo.delegateFirst) {
-            return ClassLoaderUtil.createClassLoader(appInfo.path, 
jars.toArray(new URL[jars.size()]), parent);
+            return ClassLoaderUtil.createClassLoader(appInfo.path, filtered, 
parent);
         }
-        return ClassLoaderUtil.createClassLoaderFirst(appInfo.path, 
jars.toArray(new URL[jars.size()]), parent);
+        return ClassLoaderUtil.createClassLoaderFirst(appInfo.path, filtered, 
parent);
     }
 
     public void createExternalContext(JndiContextInfo contextInfo) throws 
OpenEJBException {

Added: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/ClassLoaderConfigurer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/ClassLoaderConfigurer.java?rev=1398867&view=auto
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/ClassLoaderConfigurer.java
 (added)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/ClassLoaderConfigurer.java
 Tue Oct 16 16:08:54 2012
@@ -0,0 +1,24 @@
+/*
+ * 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.openejb.classloader;
+
+import java.net.URL;
+
+public interface ClassLoaderConfigurer {
+    URL[] additionalURLs();
+    boolean accept(final URL url);
+}

Added: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/DefaultClassLoaderConfigurer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/DefaultClassLoaderConfigurer.java?rev=1398867&view=auto
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/DefaultClassLoaderConfigurer.java
 (added)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/classloader/DefaultClassLoaderConfigurer.java
 Tue Oct 16 16:08:54 2012
@@ -0,0 +1,116 @@
+/*
+ * 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.openejb.classloader;
+
+import org.apache.openejb.config.NewLoaderLogic;
+import org.apache.openejb.loader.IO;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.URLs;
+import org.apache.xbean.finder.filter.Filter;
+import org.apache.xbean.finder.filter.Filters;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class DefaultClassLoaderConfigurer implements ClassLoaderConfigurer {
+    private static final Logger LOGGER = 
Logger.getInstance(LogCategory.OPENEJB, DefaultClassLoaderConfigurer.class);
+
+    private URL[] added;
+    private Filter excluded;
+
+    @Override
+    public URL[] additionalURLs() {
+        return added;
+    }
+
+    @Override
+    public boolean accept(final URL url) {
+        try {
+            final File file = URLs.toFile(url);
+            return !excluded.accept(file.getName());
+        } catch (IllegalArgumentException iae) {
+            return true;
+        }
+    }
+
+    public void setAddedFolder(final String addedFolder) {
+        final Collection<String> addedList = new ArrayList<String>();
+        if (addedFolder != null) {
+            final File parent = new File(addedFolder);
+            if (parent.exists()) {
+                final File[] files = parent.listFiles();
+                if (files != null) {
+                    for (File f : files) {
+                        final String name = f.getName();
+                        if (f.isDirectory() || name.endsWith(".zip") || 
name.endsWith(".jar")) {
+                            addedList.add(f.getAbsolutePath());
+                        }
+                    }
+                }
+            }
+        }
+
+        added = new URL[addedList.size()];
+        int i = 0;
+        for (String path : addedList) {
+            try {
+                added[i++] = new File(path).toURI().toURL();
+            } catch (MalformedURLException e) {
+                LOGGER.warning("Can't add file " + path, e);
+            }
+        }
+    }
+
+    public void setExcludedListFile(final String excludedListFile) {
+        String[] excludedPrefixes = null;
+        if (excludedListFile != null) {
+            final File excludedFile = new File(excludedListFile);
+            if (excludedFile.exists()) {
+                FileInputStream is = null;
+                try {
+                    is = new FileInputStream(excludedFile);
+                    excludedPrefixes = NewLoaderLogic.readInputStreamList(is);
+                } catch (FileNotFoundException e) {
+                    LOGGER.error("can't read " + excludedListFile);
+                } finally {
+                    IO.close(is);
+                }
+            }
+        }
+
+        if (excludedPrefixes == null || excludedPrefixes.length == 0) {
+            excluded = TrueFilter.INSTANCE;
+        } else {
+            excluded = Filters.prefixes(excludedPrefixes);
+        }
+    }
+
+    private static class TrueFilter implements Filter {
+        public static final TrueFilter INSTANCE = new TrueFilter();
+
+        @Override
+        public boolean accept(final String name) {
+            return true;
+        }
+    }
+}

Modified: openejb/trunk/openejb/osgi/openejb-core-osgi/pom.xml
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/osgi/openejb-core-osgi/pom.xml?rev=1398867&r1=1398866&r2=1398867&view=diff
==============================================================================
--- openejb/trunk/openejb/osgi/openejb-core-osgi/pom.xml (original)
+++ openejb/trunk/openejb/osgi/openejb-core-osgi/pom.xml Tue Oct 16 16:08:54 
2012
@@ -373,6 +373,7 @@
       org.apache.openejb.config.sys;version=${openejb.osgi.export.version},
       org.apache.openejb.core;version=${openejb.osgi.export.version},
       
org.apache.openejb.assembler.classic.event;version=${openejb.osgi.export.version},
+      org.apache.openejb.classloader;version=${openejb.osgi.export.version},
       org.apache.openejb.core.asynch;version=${openejb.osgi.export.version},
       org.apache.openejb.core.cmp;version=${openejb.osgi.export.version},
       org.apache.openejb.core.cmp.cmp2;version=${openejb.osgi.export.version},

Modified: openejb/trunk/openejb/pom.xml
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/pom.xml?rev=1398867&r1=1398866&r2=1398867&view=diff
==============================================================================
--- openejb/trunk/openejb/pom.xml (original)
+++ openejb/trunk/openejb/pom.xml Tue Oct 16 16:08:54 2012
@@ -97,7 +97,7 @@
     <maven-bundle-plugin.version>2.3.7</maven-bundle-plugin.version>
 
     <!-- This is used by a manifest classpath entry -->
-    <xbeanVersion>3.11</xbeanVersion>
+    <xbeanVersion>3.12</xbeanVersion>
 
     <!-- OSGi bundles properties -->
     <openejb.bundle.activator/>

Modified: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java?rev=1398867&r1=1398866&r2=1398867&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
 Tue Oct 16 16:08:54 2012
@@ -19,28 +19,42 @@ package org.apache.tomee.catalina;
 import org.apache.catalina.Context;
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.loader.WebappClassLoader;
+import org.apache.openejb.ClassLoaderUtil;
+import org.apache.openejb.classloader.ClassLoaderConfigurer;
 import org.apache.openejb.classloader.WebAppEnricher;
 import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.classloader.URLClassLoaderFirst;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Enumeration;
 
 public class LazyStopWebappClassLoader extends WebappClassLoader {
+    private static final Logger LOGGER = 
Logger.getInstance(LogCategory.OPENEJB, 
LazyStopWebappClassLoader.class.getName());
+
     public static final String TOMEE_WEBAPP_FIRST = "tomee.webapp-first";
 
     private boolean restarting = false;
     private volatile Context relatedContext;
     private boolean forceStopPhase = 
Boolean.parseBoolean(SystemInstance.get().getProperty("tomee.webappclassloader.force-stop-phase",
 "false"));
+    private ClassLoaderConfigurer configurer = null;
 
     public LazyStopWebappClassLoader() {
-        setDelegate(isDelegate());
+        construct();
     }
 
     public LazyStopWebappClassLoader(final ClassLoader parent) {
         super(parent);
+        construct();
+    }
+
+    private void construct() {
+        setDelegate(isDelegate());
+        configurer = 
ClassLoaderUtil.configurer(LazyStopWebappLoader.getCurrentAppId());
     }
 
     @Override
@@ -98,17 +112,47 @@ public class LazyStopWebappClassLoader e
     @Override
     public void start() throws LifecycleException {
         super.start(); // do it first otherwise we can't use this as 
classloader
-        for (URL url : 
SystemInstance.get().getComponent(WebAppEnricher.class).enrichment(this))  {
-            addURL(url);
+
+        // add configurer enrichments
+        if (configurer != null) {
+            // add now we removed all we wanted
+            final URL[] enrichment = configurer.additionalURLs();
+            for (URL url : enrichment) {
+                super.addURL(url);
+            }
+        }
+
+        // add internal enrichments
+        for (URL url : 
SystemInstance.get().getComponent(WebAppEnricher.class).enrichment(this)) {
+            super.addURL(url);
+        }
+    }
+
+    public void addURL(final URL url) {
+        if (configurer == null || configurer.accept(url)) {
+            super.addURL(url);
         }
     }
 
     @Override
     protected boolean validateJarFile(File file) throws IOException {
-        if (!super.validateJarFile(file)) {
-            return false;
+        return super.validateJarFile(file) && 
TomEEClassLoaderEnricher.validateJarFile(file) && jarIsAccepted(file);
+    }
+
+    private boolean jarIsAccepted(final File file) {
+        if (configurer == null) {
+            return true;
+        }
+
+        try {
+            if (!configurer.accept(file.toURI().toURL())) {
+                LOGGER.warning("jar '" + file.getAbsolutePath() + "' is 
excluded: " + file.getName() + ". It will be ignored.");
+                return false;
+            }
+        } catch (MalformedURLException e) {
+            // no-op
         }
-        return TomEEClassLoaderEnricher.validateJarFile(file);
+        return true;
     }
 
     public void setRelatedContext(final Context standardContext) {

Modified: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java?rev=1398867&r1=1398866&r2=1398867&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappLoader.java
 Tue Oct 16 16:08:54 2012
@@ -21,6 +21,8 @@ import org.apache.catalina.LifecycleExce
 import org.apache.catalina.loader.WebappLoader;
 
 public class LazyStopWebappLoader extends WebappLoader {
+    private static String currentAppId = null;
+
     private Context standardContext = null;
 
     public LazyStopWebappLoader(final Context ctx) {
@@ -49,10 +51,27 @@ public class LazyStopWebappLoader extend
     }
 
     @Override
-    protected void startInternal() throws LifecycleException {
-        super.startInternal();
+    protected synchronized void startInternal() throws LifecycleException {
+        currentAppId = standardContext.getName(); // needed by classloader 
instantiated by next line
+        try {
+            super.startInternal();
+        } finally {
+            currentAppId = null;
+        }
+
         if (getClassLoader() instanceof LazyStopWebappClassLoader) {
             ((LazyStopWebappClassLoader) 
getClassLoader()).setRelatedContext(standardContext);
         }
     }
+
+    public static String getCurrentAppId() {
+        return currentAppId;
+    }
+
+    public String getAppId() {
+        if (standardContext == null) {
+            return null;
+        }
+        return standardContext.getName();
+    }
 }

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=1398867&r1=1398866&r2=1398867&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
 Tue Oct 16 16:08:54 2012
@@ -814,9 +814,9 @@ public class TomcatWebAppBuilder impleme
 
         // we just want to wrap it to lazy stop it (afterstop)
         // to avoid classnotfound in @PreDestoy or destroyApplication()
-        final Loader loader = new LazyStopWebappLoader(standardContext);
+        final WebappLoader loader = new LazyStopWebappLoader(standardContext);
         loader.setDelegate(standardContext.getDelegate());
-        ((WebappLoader) 
loader).setLoaderClass(LazyStopWebappClassLoader.class.getName());
+        loader.setLoaderClass(LazyStopWebappClassLoader.class.getName());
         final Loader lazyStopLoader = new LazyStopLoader(loader);
         standardContext.setLoader(lazyStopLoader);
     }


Reply via email to