Hi, added org.apache.tomee.catalina.TomEEClassLoaderHelper#tomEEWebappIntegrationLibraries, the goal is to be able to enrich the webappclassloader with some of our jars.
The idea was to be able to let the users provide implementation in the webapp without having to know too much about us. Typically our JPA and JSF integrations are good examples. For JPA (the simpler ;)) and hibernate today the JtaPlatform (or manager lookup) needs to be added in the webapp since our class is not laodable from common classloader. With this enrichment the webapp get automatically this jar and it works fine. It still work if hibernate is in common lib since we still provide it. I think it'll help us too to be able to support a bit more mojarra as JSF implementation. /me hopes it doesn't break something i didn't think of - Romain ---------- Forwarded message ---------- From: <[email protected]> Date: 2012/7/1 Subject: svn commit: r1355952 - in /openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina: LazyStopWebappClassLoader.java TomEEClassLoaderHelper.java TomEEWebappLoader.java To: [email protected] Author: rmannibucau Date: Sun Jul 1 16:53:09 2012 New Revision: 1355952 URL: http://svn.apache.org/viewvc?rev=1355952&view=rev Log: TOMEE-261 enriching webapp classloaders with jpa integration and jsf jars Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEClassLoaderHelper.java Modified: 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/TomEEWebappLoader.java 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=1355952&r1=1355951&r2=1355952&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 Sun Jul 1 16:53:09 2012 @@ -20,6 +20,8 @@ import org.apache.catalina.LifecycleExce import org.apache.catalina.loader.WebappClassLoader; import org.apache.openejb.loader.SystemInstance; +import java.net.URL; + public class LazyStopWebappClassLoader extends WebappClassLoader { public static final String TOMEE_WEBAPP_FIRST = "tomee.webapp-first"; @@ -59,4 +61,17 @@ public class LazyStopWebappClassLoader e public boolean isRestarting() { return restarting; } + + // embeddeding implementation of sthg (JPA, JSF) can lead to classloading issues if we don't enrich the webapp + // with our integration jars + // typically the class will try to be loaded by the common classloader + // but the interface implemented or the parent class + // will be in the webapp + @Override + public void start() throws LifecycleException { + for (URL url : TomEEClassLoaderHelper.tomEEWebappIntegrationLibraries()) { + addURL(url); + } + super.start(); + } } Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEClassLoaderHelper.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEClassLoaderHelper.java?rev=1355952&view=auto ============================================================================== --- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEClassLoaderHelper.java (added) +++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEClassLoaderHelper.java Sun Jul 1 16:53:09 2012 @@ -0,0 +1,66 @@ +package org.apache.tomee.catalina; + +import org.apache.openejb.OpenEJB; +import org.apache.openejb.loader.SystemInstance; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +public final class TomEEClassLoaderHelper { + public static final String TOMEE_WEBAPP_CLASSLOADER_ENRICHMENT_SKIP = "tomee.webapp.classloader.enrichment.skip"; + public static final String TOMEE_WEBAPP_CLASSLOADER_ENRICHMENT = "tomee.webapp.classloader.enrichment"; + + private static final String[] DEFAULT_JAR_TO_ADD_CLASS_HELPERS = new String[] { + // openejb-jsf and openwebbeans-jsf to be able to embedded the jsf impl keeping CDI features + "org.apache.openejb.jsf.CustomApplicationFactory", + "org.apache.webbeans.jsf.OwbApplicationFactory", + + // JPA integration: mainly JTA integration + "org.apache.openejb.jpa.integration.MakeTxLookup" + }; + private static final String[] JAR_TO_ADD_CLASS_HELPERS; + + static { + final Collection<String> classes = new ArrayList<String>(); + if (!SystemInstance.get().getOptions().get(TOMEE_WEBAPP_CLASSLOADER_ENRICHMENT_SKIP, false)) { + classes.addAll(Arrays.asList(DEFAULT_JAR_TO_ADD_CLASS_HELPERS)); + + final String additionalEnrichments = SystemInstance.get().getOptions().get(TOMEE_WEBAPP_CLASSLOADER_ENRICHMENT, ""); + if (additionalEnrichments != null && !additionalEnrichments.isEmpty()) { + for (String name : additionalEnrichments.split(",")) { + classes.add(name.trim()); + } + } + } + JAR_TO_ADD_CLASS_HELPERS = classes.toArray(new String[classes.size()]); + } + + private TomEEClassLoaderHelper() { + // no-op + } + + public static URL[] tomEEWebappIntegrationLibraries() { + final ClassLoader cl = TomEEClassLoaderHelper.class.getClassLoader(); // reference classloader = standardclassloader + final Collection<URL> urls = new ArrayList<URL>(); + for (String name : JAR_TO_ADD_CLASS_HELPERS) { + try { + final Class<?> clazz = cl.loadClass(name); + if (!clazz.getClassLoader().equals(OpenEJB.class.getClassLoader())) { // already provided? + continue; + } + + final URL url = clazz.getProtectionDomain().getCodeSource().getLocation(); + if (url == null) { + continue; + } + + urls.add(url); + } catch (Exception e) { + // ignore + } + } + return urls.toArray(new URL[urls.size()]); + } +} Modified: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEWebappLoader.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEWebappLoader.java?rev=1355952&r1=1355951&r2=1355952&view=diff ============================================================================== --- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEWebappLoader.java (original) +++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomEEWebappLoader.java Sun Jul 1 16:53:09 2012 @@ -126,12 +126,24 @@ public class TomEEWebappLoader extends W private final HashMap<Class, Object> components = new HashMap<Class, Object>(); public TomEEClassLoader(final String appId, final ClassLoader appCl, final WebappClassLoader webappCl) { - super(webappCl.getURLs(), webappCl); // in fact this classloader = webappclassloader since we add nothing to this + super(enrichedUrls(webappCl.getURLs()), webappCl); // in fact this classloader = webappclassloader since we add nothing to this this.appPath = appId; this.app = appCl; // only used to manage resources since webapp.getParent() should be app this.webapp = webappCl; } + private static URL[] enrichedUrls(final URL[] urLs) { + final URL[] additional = TomEEClassLoaderHelper.tomEEWebappIntegrationLibraries(); + final URL[] urls = new URL[urLs.length + additional.length]; + for (int i = 0; i < urLs.length; i++) { + urls[i] = urLs[i]; + } + for (int i = 0; i < additional.length; i++) { + urls[urLs.length + i] = additional[i]; + } + return urls; + } + public <T> T getComponent(final Class<T> type) { return (T) components.get(type); }
