Author: musachy Date: Sun Apr 5 23:45:49 2009 New Revision: 762186 URL: http://svn.apache.org/viewvc?rev=762186&view=rev Log: Use ClassLoaderInterface for resource finding and class loading
Modified: struts/struts2/trunk/plugins/convention/pom.xml struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/classloader/ReloadingClassLoader.java Modified: struts/struts2/trunk/plugins/convention/pom.xml URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/pom.xml?rev=762186&r1=762185&r2=762186&view=diff ============================================================================== --- struts/struts2/trunk/plugins/convention/pom.xml (original) +++ struts/struts2/trunk/plugins/convention/pom.xml Sun Apr 5 23:45:49 2009 @@ -1,4 +1,5 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache.struts</groupId> @@ -11,9 +12,11 @@ <name>Struts 2 Convention Plugin</name> <scm> - <connection>scm:svn:http://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-convention-plugin</connection> - <developerConnection>scm:svn:https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-convention-plugin</developerConnection> - <url>http://svn.apache.org/viewcvs.cgi/struts/sandbox/trunk/struts2-convention-plugin</url> + <connection>scm:svn:http://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-convention-plugin</connection> + <developerConnection> + scm:svn:https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-convention-plugin + </developerConnection> + <url>http://svn.apache.org/viewcvs.cgi/struts/sandbox/trunk/struts2-convention-plugin</url> </scm> <build> @@ -31,7 +34,19 @@ </execution> </executions> </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Activator>org.apache.struts2.osgi.StrutsActivator</Bundle-Activator> + <manifestLocation>META-INF</manifestLocation> + </instructions> + </configuration> + </plugin> </plugins> + </build> <dependencies> <dependency> Modified: struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java?rev=762186&r1=762185&r2=762186&view=diff ============================================================================== --- struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java (original) +++ struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java Sun Apr 5 23:45:49 2009 @@ -33,8 +33,10 @@ import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.apache.commons.lang.xwork.StringUtils; +import org.apache.commons.lang.xwork.ObjectUtils; import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.PackageConfig; import com.opensymphony.xwork2.config.entities.ResultConfig; @@ -43,6 +45,8 @@ import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.finder.ResourceFinder; import com.opensymphony.xwork2.util.finder.Test; +import com.opensymphony.xwork2.util.finder.ClassLoaderInterface; +import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; @@ -267,7 +271,7 @@ actionName); } - ResourceFinder finder = new ResourceFinder(classPathLocation); + ResourceFinder finder = new ResourceFinder(classPathLocation, getClassLoaderInterface()); try { Map<String, URL> matches = finder.getResourcesMap(""); if (matches != null) { @@ -290,6 +294,24 @@ if (LOG.isErrorEnabled()) LOG.error("Unable to scan directory [#0] for results", ex, classPathLocation); } + } + + protected ClassLoaderInterface getClassLoaderInterface() { + + /* + if there is a ClassLoaderInterface in the context, use it, otherwise + default to the default ClassLoaderInterface (a wrapper around the current + thread classloader) + using this, other plugins (like OSGi) can plugin their own classloader for a while + and it will be used by Convention (it cannot be a bean, as Convention is likely to be + called multiple times, and it need to use the default ClassLoaderInterface during normal startup) + */ + ClassLoaderInterface classLoaderInterface = null; + ActionContext ctx = ActionContext.getContext(); + if (ctx != null) + classLoaderInterface = (ClassLoaderInterface) ctx.get(ClassLoaderInterface.CLASS_LOADER_INTERFACE); + + return (ClassLoaderInterface) ObjectUtils.defaultIfNull(classLoaderInterface, new ClassLoaderInterfaceDelegate(Thread.currentThread().getContextClassLoader())); } Modified: struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java?rev=762186&r1=762185&r2=762186&view=diff ============================================================================== --- struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java (original) +++ struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java Sun Apr 5 23:45:49 2009 @@ -21,6 +21,7 @@ package org.apache.struts2.convention; import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.ActionConfig; @@ -35,9 +36,12 @@ import com.opensymphony.xwork2.util.finder.ClassFinder; import com.opensymphony.xwork2.util.finder.Test; import com.opensymphony.xwork2.util.finder.UrlSet; +import com.opensymphony.xwork2.util.finder.ClassLoaderInterface; +import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; import org.apache.commons.lang.xwork.StringUtils; +import org.apache.commons.lang.xwork.ObjectUtils; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsException; import org.apache.struts2.convention.annotation.Action; @@ -248,6 +252,11 @@ if (isReloadEnabled() && reloadingClassLoader == null) reloadingClassLoader = new ReloadingClassLoader(getClassLoader()); } + + private ClassLoader getClassLoader() { + return Thread.currentThread().getContextClassLoader(); + } + /** * Builds the action configurations by loading all classes in the packages specified by the * property <b>struts.convention.action.packages</b> and then figuring out which classes implement Action @@ -287,8 +296,25 @@ } } - protected ClassLoader getClassLoaderForFinder() { - return isReloadEnabled() ? this.reloadingClassLoader : getClassLoader(); + protected ClassLoaderInterface getClassLoaderInterface() { + if (isReloadEnabled()) + return new ClassLoaderInterfaceDelegate(this.reloadingClassLoader); + else { + /* + if there is a ClassLoaderInterface in the context, use it, otherwise + default to the default ClassLoaderInterface (a wrapper around the current + thread classloader) + using this, other plugins (like OSGi) can plugin their own classloader for a while + and it will be used by Convention (it cannot be a bean, as Convention is likely to be + called multiple times, and it need to use the default ClassLoaderInterface during normal startup) + */ + ClassLoaderInterface classLoaderInterface = null; + ActionContext ctx = ActionContext.getContext(); + if (ctx != null) + classLoaderInterface = (ClassLoaderInterface) ctx.get(ClassLoaderInterface.CLASS_LOADER_INTERFACE); + + return (ClassLoaderInterface) ObjectUtils.defaultIfNull(classLoaderInterface, new ClassLoaderInterfaceDelegate(getClassLoader())); + } } protected boolean isReloadEnabled() { @@ -300,7 +326,7 @@ Set<Class> classes = new HashSet<Class>(); try { if (actionPackages != null || (packageLocators != null && !disablePackageLocatorsScanning)) { - ClassFinder finder = new ClassFinder(getClassLoaderForFinder(), buildUrlSet().getUrls(), true, this.fileProtocols); + ClassFinder finder = new ClassFinder(getClassLoaderInterface(), buildUrlSet().getUrls(), true, this.fileProtocols); // named packages if (actionPackages != null) { @@ -327,9 +353,14 @@ } private UrlSet buildUrlSet() throws IOException { - UrlSet urlSet = new UrlSet(getClassLoader()); + ClassLoaderInterface classLoaderInterface = getClassLoaderInterface(); + UrlSet urlSet = new UrlSet(classLoaderInterface); + + //exclude parent of classloaders + if (classLoaderInterface.getParent() != null) + urlSet = urlSet.exclude(classLoaderInterface.getParent()); - urlSet = urlSet.exclude(ClassLoader.getSystemClassLoader().getParent()); + urlSet = urlSet.exclude(new ClassLoaderInterfaceDelegate(ClassLoader.getSystemClassLoader().getParent())); urlSet = urlSet.excludeJavaExtDirs(); urlSet = urlSet.excludeJavaEndorsedDirs(); urlSet = urlSet.excludeJavaHome(); @@ -374,10 +405,6 @@ return urlSet; } - private ClassLoader getClassLoader() { - return Thread.currentThread().getContextClassLoader(); - } - protected Test<ClassFinder.ClassInfo> getPackageFinderTest(final String packageName) { // so "my.package" does not match "my.package2.test" final String strictPackageName = packageName + "."; Modified: struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/classloader/ReloadingClassLoader.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/classloader/ReloadingClassLoader.java?rev=762186&r1=762185&r2=762186&view=diff ============================================================================== --- struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/classloader/ReloadingClassLoader.java (original) +++ struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/classloader/ReloadingClassLoader.java Sun Apr 5 23:45:49 2009 @@ -32,9 +32,9 @@ /** - * The ReloadingClassLoader uses a delegation mechansim to allow + * The ReloadingClassLoader uses a delegation mechanism to allow * classes to be reloaded. That means that loadClass calls may - * return different results if the class was change in the underlying + * return different results if the class was changed in the underlying * ResoruceStore. * <p/> * class taken from Apache JCI