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);
}