Author: hlship
Date: Tue Mar 6 15:35:00 2007
New Revision: 515362
URL: http://svn.apache.org/viewvc?view=rev&rev=515362
Log:
TAPESTRY-1316: Address class loader issues inside JBoss
Modified:
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java
tapestry/tapestry5/tapestry-project/trunk/src/site/apt/jboss.apt
Modified:
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java?view=diff&rev=515362&r1=515361&r2=515362
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java
(original)
+++
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java
Tue Mar 6 15:35:00 2007
@@ -15,8 +15,10 @@
package org.apache.tapestry.ioc.internal.services;
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
import java.util.Set;
+import java.util.Map;
import javassist.ClassPath;
import javassist.ClassPool;
@@ -31,14 +33,12 @@
*/
public class ClassFactoryClassPool extends ClassPool
{
- private ClassLoader _loader;
-
- private ClassPath _priorClassPath;
-
/**
* Used to identify which class loaders have already been integrated into
the pool.
*/
- private Set<ClassLoader> _loaders = newSet();
+ private final Set<ClassLoader> _allLoaders = newSet();
+
+ private final Map<ClassLoader, ClassPath> _leafLoaders = newMap();
public ClassFactoryClassPool(ClassLoader contextClassLoader)
{
@@ -50,9 +50,6 @@
/**
* Convienience method for adding to the ClassPath for a particular class
loader.
* <p>
- * TODO: This code assumes that ClassLoaders are structured as a "line"
not a proper "tree".
- * That is, if the ClassLoader hiearchy actually does have branches,
rather than a straight line
- * from root to leaf, it may not work.
*
* @param loader
* the class loader to add (derived from a loaded class, and
may be null for some
@@ -60,28 +57,34 @@
*/
public synchronized void addClassLoaderIfNeeded(ClassLoader loader)
{
- if (loader == null || loader == _loader || _loaders.contains(loader))
return;
+ Set<ClassLoader> leaves = _leafLoaders.keySet();
+ if (loader == null || leaves.contains(loader) ||
_allLoaders.contains(loader)) return;
- ClassPath path = new LoaderClassPath(loader);
+ // Work out if this loader is a child of a loader we have already.
+ ClassLoader existingLeaf = loader;
+ while (existingLeaf != null && !leaves.contains(existingLeaf))
+ {
+ existingLeaf = existingLeaf.getParent();
+ }
- if (_priorClassPath != null) removeClassPath(_priorClassPath);
+ if (existingLeaf != null)
+ {
+ // The new loader is a child of an existing leaf.
+ // So we remove the old leaf before we add the new loader
+ ClassPath priorPath = _leafLoaders.get(existingLeaf);
+ removeClassPath(priorPath);
+ _leafLoaders.remove(existingLeaf);
+ }
+ ClassPath path = new LoaderClassPath(loader);
+ _leafLoaders.put(loader, path);
insertClassPath(path);
- _priorClassPath = path;
-
ClassLoader l = loader;
while (l != null)
{
- _loaders.add(l);
+ _allLoaders.add(l);
l = l.getParent();
}
-
- _loader = loader;
- }
-
- public synchronized ClassLoader getLoader()
- {
- return _loader;
}
}
Modified: tapestry/tapestry5/tapestry-project/trunk/src/site/apt/jboss.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-project/trunk/src/site/apt/jboss.apt?view=diff&rev=515362&r1=515361&r2=515362
==============================================================================
--- tapestry/tapestry5/tapestry-project/trunk/src/site/apt/jboss.apt (original)
+++ tapestry/tapestry5/tapestry-project/trunk/src/site/apt/jboss.apt Tue Mar 6
15:35:00 2007
@@ -5,25 +5,7 @@
Deployment Notes: JBoss
JBoss's default servlet container is {{{tomcat.html}Tomcat}}, so deployment
notes for Tomcat apply to JBoss as well.
-
- JBoss has a very odd class loader structure that causes havoc with many
frameworks, including Tapestry 5. The way to get around it is to edit the
configuration file
- <JBoss
root>/server/default/deploy/jbossweb-tomcat55.sar/META-INF/jboss-service.xml
and turn on the UseJBossWebLoader attribute:
-
-+----+
- <!-- A flag indicating if the JBoss Loader should be used. This loader
- uses a unified class loader as the class loader rather than the
tomcat
- specific class loader.
- The default is false to ensure that wars have isolated class loading
- for duplicate jars and jsp files.
- -->
- <attribute name="UseJBossWebLoader">true</attribute>
-+----+
-
- This is not a very good solution, as it affects all web applications within
the server, potentially causing other problems. Hopefully a better solution will
- be discoverred in the future. And perhaps a time traveller will venture back
in time with that information and save me a lot of headaches yesterday.
-
- Tapestry has been tested with JBoss 4.0.5, which uses Tomcat 5.5.20.
-
+
* Logging
TODO: Discuss logging configuration for JBoss.