diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java b/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java index 7803ba836..2c24dd3ba 100644 --- a/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java @@ -65,6 +65,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -80,6 +81,7 @@ import java.util.regex.Pattern; public class PackageBasedActionConfigBuilder implements ActionConfigBuilder { private static final Logger LOG = LoggerFactory.getLogger(PackageBasedActionConfigBuilder.class); + private static final boolean EXTRACT_BASE_INTERFACES = true; private final Configuration configuration; private final ActionNameBuilder actionNameBuilder; @@ -384,7 +386,8 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder { // only considers classes that match the action packages // specified by the user Test classPackageTest = getClassPackageTest(); - ClassFinder finder = new ClassFinder(getClassLoaderInterface(), buildUrlSet().getUrls(), true, this.fileProtocols, classPackageTest); + List urls = readUrls(); + ClassFinder finder = new ClassFinder(getClassLoaderInterface(), urls, EXTRACT_BASE_INTERFACES, fileProtocols, classPackageTest); Test test = getActionClassTest(); classes.addAll(finder.findClasses(test)); @@ -397,9 +400,19 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder { return classes; } + private List readUrls() throws IOException { + List list = buildUrlSet().getUrls(); + // Usually the "classes" dir. + ArrayList classesList = Collections.list(getClassLoaderInterface().getResources("")); + for (URL url : classesList) { + list.addAll(fileManager.getAllPhysicalUrls(url)); + } + return list; + } + private UrlSet buildUrlSet() throws IOException { ClassLoaderInterface classLoaderInterface = getClassLoaderInterface(); - UrlSet urlSet = new UrlSet(fileManager, classLoaderInterface, this.fileProtocols); + UrlSet urlSet = new UrlSet(classLoaderInterface, this.fileProtocols); //excluding the urls found by the parent class loader is desired, but fails in JBoss (all urls are removed) if (excludeParentClassLoader) { @@ -425,7 +438,11 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder { } //try to find classes dirs inside war files - urlSet = urlSet.includeClassesUrl(classLoaderInterface); + urlSet = urlSet.includeClassesUrl(classLoaderInterface, new UrlSet.FileProtocolNormalizer() { + public URL normalizeToFileProtocol(URL url) { + return fileManager.normalizeToFileProtocol(url); + } + }); urlSet = urlSet.excludeJavaExtDirs(); @@ -472,7 +489,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder { } } } - return new UrlSet(fileManager, includeUrls); + return new UrlSet(includeUrls); } return urlSet; diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java index 5d02973e8..d73850056 100644 --- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java +++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java @@ -184,7 +184,7 @@ public class JSPLoader { //find available jars ClassLoaderInterface classLoaderInterface = getClassLoaderInterface(); - UrlSet urlSet = new UrlSet(fileManager, classLoaderInterface); + UrlSet urlSet = new UrlSet(classLoaderInterface); //find jars List urls = urlSet.getUrls(); diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java b/xwork-core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java index f6b57fa5b..ded02efb8 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java @@ -15,7 +15,6 @@ */ package com.opensymphony.xwork2.util.finder; -import com.opensymphony.xwork2.FileManager; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; import org.apache.commons.lang3.ObjectUtils; @@ -26,6 +25,7 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; @@ -50,40 +50,41 @@ import java.util.Set; * @version $Rev$ $Date$ */ public class UrlSet { + private static final Logger LOG = LoggerFactory.getLogger(UrlSet.class); + private final Map urls; private Set protocols; - private FileManager fileManager; - public UrlSet(FileManager fileManager, ClassLoaderInterface classLoader) throws IOException { - this(fileManager); + private UrlSet() { + this.urls = new HashMap(); + } + + public UrlSet(ClassLoaderInterface classLoader) throws IOException { + this(); load(getUrls(classLoader)); } - public UrlSet(FileManager fileManager, ClassLoaderInterface classLoader, Set protocols) throws IOException { - this(fileManager); + public UrlSet(ClassLoaderInterface classLoader, Set protocols) throws IOException { + this(); this.protocols = protocols; - this.fileManager = fileManager; load(getUrls(classLoader, protocols)); } + public UrlSet(URL... urls){ + this(Arrays.asList(urls)); + } /** * Ignores all URLs that are not "jar" or "file" * @param urls */ - public UrlSet(FileManager fileManager, Collection urls){ - this(fileManager); + public UrlSet(Collection urls){ + this(); load(urls); } - private UrlSet(FileManager fileManager) { - this.urls = new HashMap(); - this.fileManager = fileManager; - } - - private UrlSet(FileManager fileManager, Map urls) { + private UrlSet(Map urls) { this.urls = urls; - this.fileManager = fileManager; } private void load(Collection urls){ @@ -91,7 +92,9 @@ public class UrlSet { try { this.urls.put(location.toExternalForm(), location); } catch (Exception e) { - e.printStackTrace(); + if (LOG.isWarnEnabled()) { + LOG.warn("Cannot translate url to external form!", e); + } } } } @@ -99,7 +102,7 @@ public class UrlSet { public UrlSet include(UrlSet urlSet){ Map urls = new HashMap(this.urls); urls.putAll(urlSet.urls); - return new UrlSet(fileManager, urls); + return new UrlSet(urls); } public UrlSet exclude(UrlSet urlSet) { @@ -108,11 +111,11 @@ public class UrlSet { for (String url : parentUrls.keySet()) { urls.remove(url); } - return new UrlSet(fileManager, urls); + return new UrlSet(urls); } public UrlSet exclude(ClassLoaderInterface parent) throws IOException { - return exclude(new UrlSet(fileManager, parent, this.protocols)); + return exclude(new UrlSet(parent, this.protocols)); } public UrlSet exclude(File file) throws MalformedURLException { @@ -177,13 +180,13 @@ public class UrlSet { urls.put(url, entry.getValue()); } } - return new UrlSet(fileManager, urls); + return new UrlSet(urls); } /** * Try to find a classes directory inside a war file add its normalized url to this set */ - public UrlSet includeClassesUrl(ClassLoaderInterface classLoaderInterface) throws IOException { + public UrlSet includeClassesUrl(ClassLoaderInterface classLoaderInterface, FileProtocolNormalizer normalizer) throws IOException { Enumeration rootUrlEnumeration = classLoaderInterface.getResources(""); while (rootUrlEnumeration.hasMoreElements()) { URL url = rootUrlEnumeration.nextElement(); @@ -192,14 +195,14 @@ public class UrlSet { //if it is inside a war file, get the url to the file externalForm = StringUtils.substringBefore(externalForm, "/WEB-INF/classes"); URL warUrl = new URL(externalForm); - URL normalizedUrl = fileManager.normalizeToFileProtocol(warUrl); + URL normalizedUrl = normalizer.normalizeToFileProtocol(warUrl); URL finalUrl = ObjectUtils.defaultIfNull(normalizedUrl, warUrl); Map newUrls = new HashMap(this.urls); if ("jar".equals(finalUrl.getProtocol()) || "file".equals(finalUrl.getProtocol())) { newUrls.put(finalUrl.toExternalForm(), finalUrl); } - return new UrlSet(fileManager, newUrls); + return new UrlSet(newUrls); } } @@ -207,7 +210,7 @@ public class UrlSet { } public UrlSet relative(File file) throws MalformedURLException { - String urlPath = file.toURL().toExternalForm(); + String urlPath = file.toURI().toURL().toExternalForm(); Map urls = new HashMap(); for (Map.Entry entry : this.urls.entrySet()) { String url = entry.getKey(); @@ -215,7 +218,7 @@ public class UrlSet { urls.put(url, entry.getValue()); } } - return new UrlSet(fileManager, urls); + return new UrlSet(urls); } public List getUrls() { @@ -265,14 +268,13 @@ public class UrlSet { LOG.debug("Ignoring URL [#0] because it is not a valid protocol", url.toExternalForm()); } - - // Usually the "classes" dir. - ArrayList classesList = Collections.list(classLoader.getResources("")); - for (URL url : classesList) { - list.addAll(fileManager.getAllPhysicalUrls(url)); - } - return list; } + public static interface FileProtocolNormalizer { + + URL normalizeToFileProtocol(URL url); + + } + }