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

Reply via email to