Author: gnodet
Date: Tue Oct 31 11:57:34 2006
New Revision: 469628
URL: http://svn.apache.org/viewvc?view=rev&rev=469628
Log:
SM-729: Inverse classloader definition in xbean SU with default locations
Modified:
incubator/servicemix/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/ClassLoaderXmlPreprocessor.java
incubator/servicemix/trunk/servicemix-common/src/test/resources/xbean-inline/xbean.xml
Modified:
incubator/servicemix/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/ClassLoaderXmlPreprocessor.java
URL:
http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/ClassLoaderXmlPreprocessor.java?view=diff&rev=469628&r1=469627&r2=469628
==============================================================================
---
incubator/servicemix/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/ClassLoaderXmlPreprocessor.java
(original)
+++
incubator/servicemix/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/ClassLoaderXmlPreprocessor.java
Tue Oct 31 11:57:34 2006
@@ -18,7 +18,11 @@
import java.io.File;
import java.io.FilenameFilter;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
import javax.xml.parsers.DocumentBuilder;
@@ -29,10 +33,12 @@
import org.apache.xbean.server.spring.loader.SpringLoader;
import org.apache.xbean.spring.context.SpringApplicationContext;
import org.apache.xbean.spring.context.SpringXmlPreprocessor;
-import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
/**
* An advanced xml preprocessor that will create a default classloader for the
SU if none
@@ -46,18 +52,17 @@
public static final String LIB_DIR = "/lib";
private final FileSystemRepository repository;
- private final SpringXmlPreprocessor preprocessor;
public ClassLoaderXmlPreprocessor(Repository repository) {
if (repository instanceof FileSystemRepository == false) {
throw new IllegalArgumentException("repository must be a
FileSystemRepository");
}
this.repository = (FileSystemRepository) repository;
- this.preprocessor = new
org.apache.xbean.server.spring.configuration.ClassLoaderXmlPreprocessor(repository);
}
public void preprocess(SpringApplicationContext applicationContext,
XmlBeanDefinitionReader reader, Document document) {
// determine the classLoader
+ ClassLoader classLoader;
NodeList classpathElements =
document.getDocumentElement().getElementsByTagName("classpath");
if (classpathElements.getLength() == 0) {
// Check if a classpath.xml file exists in the root of the SU
@@ -66,45 +71,128 @@
try {
DocumentBuilder builder = new
SourceTransformer().createDocumentBuilder();
Document doc = builder.parse(url.toString());
- preprocessor.preprocess(applicationContext, reader, doc);
+ classLoader = getClassLoader(applicationContext, reader,
doc);
} catch (Exception e) {
- throw new BeanDefinitionStoreException("Unable to load
classpath.xml file", e);
+ throw new FatalBeanException("Unable to load classpath.xml
file", e);
}
} else {
try {
- File root = repository.getRoot();
- File[] jars = new File(root, LIB_DIR).listFiles(new
FilenameFilter() {
- public boolean accept(File dir, String name) {
- name = name.toLowerCase();
- return name.endsWith(".jar") ||
name.endsWith(".zip");
- }
- });
- URL[] urls = new URL[jars != null ? jars.length + 1 : 1];
- urls[0] = root.toURL();
- if (jars != null) {
- for (int i = 0; i < jars.length; i++) {
- urls[i+1] = jars[i].toURL();
- }
- }
- ClassLoader parentLoader =
getClassLoader(applicationContext);
- ClassLoader classLoader = new JarFileClassLoader(
-
applicationContext.getDisplayName(),
- urls,
- parentLoader);
- // assign the class loader to the xml reader and the
application context
- reader.setBeanClassLoader(classLoader);
- applicationContext.setClassLoader(classLoader);
- Thread.currentThread().setContextClassLoader(classLoader);
+ URL[] urls = getDefaultLocations();
+ ClassLoader parentLoader =
getParentClassLoader(applicationContext);
+ classLoader = new
JarFileClassLoader(applicationContext.getDisplayName(), urls, parentLoader);
+ // assign the class loader to the xml reader and the
+ // application context
} catch (Exception e) {
- throw new BeanDefinitionStoreException("Unable to create
default classloader for SU", e);
+ throw new FatalBeanException("Unable to create default
classloader for SU", e);
}
}
} else {
- preprocessor.preprocess(applicationContext, reader, document);
+ classLoader = getClassLoader(applicationContext, reader, document);
+ }
+ reader.setBeanClassLoader(classLoader);
+ applicationContext.setClassLoader(classLoader);
+ Thread.currentThread().setContextClassLoader(classLoader);
+ }
+
+ protected URL[] getDefaultLocations() {
+ try {
+ File root = repository.getRoot();
+ File[] jars = new File(root, LIB_DIR).listFiles(new
FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ name = name.toLowerCase();
+ return name.endsWith(".jar") || name.endsWith(".zip");
+ }
+ });
+ URL[] urls = new URL[jars != null ? jars.length + 1 : 1];
+ urls[0] = root.toURL();
+ if (jars != null) {
+ for (int i = 0; i < jars.length; i++) {
+ urls[i+1] = jars[i].toURL();
+ }
+ }
+ return urls;
+ } catch (MalformedURLException e) {
+ throw new FatalBeanException("Unable to get default classpath
locations", e);
+ }
+ }
+
+ protected ClassLoader getClassLoader(SpringApplicationContext
applicationContext, XmlBeanDefinitionReader reader, Document document) {
+ // determine the classLoader
+ ClassLoader classLoader;
+ NodeList classpathElements =
document.getDocumentElement().getElementsByTagName("classpath");
+ if (classpathElements.getLength() < 1) {
+ classLoader = getParentClassLoader(applicationContext);
+ } else if (classpathElements.getLength() > 1) {
+ throw new FatalBeanException("Expected only classpath element but
found " + classpathElements.getLength());
+ } else {
+ Element classpathElement = (Element) classpathElements.item(0);
+
+ // Delegation mode
+ boolean inverse = false;
+ String inverseAttr = classpathElement.getAttribute("inverse");
+ if (inverseAttr != null && "true".equalsIgnoreCase(inverseAttr)) {
+ inverse = true;
+ }
+
+ // build hidden classes
+ List hidden = new ArrayList();
+ NodeList hiddenElems =
classpathElement.getElementsByTagName("hidden");
+ for (int i = 0; i < hiddenElems.getLength(); i++) {
+ Element hiddenElement = (Element) hiddenElems.item(i);
+ String pattern = ((Text)
hiddenElement.getFirstChild()).getData().trim();
+ hidden.add(pattern);
+ }
+
+ // build non overridable classes
+ List nonOverridable = new ArrayList();
+ NodeList nonOverridableElems =
classpathElement.getElementsByTagName("nonOverridable");
+ for (int i = 0; i < nonOverridableElems.getLength(); i++) {
+ Element nonOverridableElement = (Element)
nonOverridableElems.item(i);
+ String pattern = ((Text)
nonOverridableElement.getFirstChild()).getData().trim();
+ nonOverridable.add(pattern);
+ }
+
+ // build the classpath
+ List classpath = new ArrayList();
+ NodeList locations =
classpathElement.getElementsByTagName("location");
+ for (int i = 0; i < locations.getLength(); i++) {
+ Element locationElement = (Element) locations.item(i);
+ String location = ((Text)
locationElement.getFirstChild()).getData().trim();
+ classpath.add(location);
+ }
+
+ // convert the paths to URLS
+ URL[] urls;
+ if (classpath.size() != 0) {
+ urls = new URL[classpath.size()];
+ for (ListIterator iterator = classpath.listIterator();
iterator.hasNext();) {
+ String location = (String) iterator.next();
+ URL url = repository.getResource(location);
+ if (url == null) {
+ throw new FatalBeanException("Unable to resolve
classpath location " + location);
+ }
+ urls[iterator.previousIndex()] = url;
+ }
+ } else {
+ urls = getDefaultLocations();
+ }
+
+ // create the classloader
+ ClassLoader parentLoader =
getParentClassLoader(applicationContext);
+ classLoader = new
JarFileClassLoader(applicationContext.getDisplayName(),
+ urls,
+ parentLoader,
+ inverse,
+ (String[]) hidden.toArray(new
String[hidden.size()]),
+ (String[])
nonOverridable.toArray(new String[nonOverridable.size()]));
+
+ // remove the classpath element so Spring doesn't get confused
+ document.getDocumentElement().removeChild(classpathElement);
}
+ return classLoader;
}
- private static ClassLoader getClassLoader(SpringApplicationContext
applicationContext) {
+ private static ClassLoader getParentClassLoader(SpringApplicationContext
applicationContext) {
ClassLoader classLoader = applicationContext.getClassLoader();
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
Modified:
incubator/servicemix/trunk/servicemix-common/src/test/resources/xbean-inline/xbean.xml
URL:
http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-common/src/test/resources/xbean-inline/xbean.xml?view=diff&rev=469628&r1=469627&r2=469628
==============================================================================
---
incubator/servicemix/trunk/servicemix-common/src/test/resources/xbean-inline/xbean.xml
(original)
+++
incubator/servicemix/trunk/servicemix-common/src/test/resources/xbean-inline/xbean.xml
Tue Oct 31 11:57:34 2006
@@ -19,10 +19,7 @@
-->
<beans>
- <classpath>
- <location>.</location>
- <location>lib/classpath.zip</location>
- </classpath>
+ <classpath inverse="true" />
<bean class="org.apache.servicemix.common.xbean.XBeanEndpoint">
<property name="service" value="service"/>