General defensiveness about the bootstrap ClassLoader (i.e. null ClassLoader)
Issue: SPR-11721
(cherry picked from commit 59cef3c)
This commit is contained in:
@@ -42,6 +42,7 @@ import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.core.io.VfsResource;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
@@ -143,11 +144,15 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* <p><b>WARNING:</b> Ant-style patterns with "classpath:" resources are not
|
||||
* guaranteed to find matching resources if the root package to search is available
|
||||
* in multiple class path locations. This is because a resource such as<pre class="code">
|
||||
* in multiple class path locations. This is because a resource such as
|
||||
* <pre class="code">
|
||||
* com/mycompany/package1/service-context.xml
|
||||
* </pre>may be in only one location, but when a path such as<pre class="code">
|
||||
* </pre>
|
||||
* may be in only one location, but when a path such as
|
||||
* <pre class="code">
|
||||
* classpath:com/mycompany/**/service-context.xml
|
||||
* </pre>is used to try to resolve it, the resolver will work off the (first) URL
|
||||
* </pre>
|
||||
* is used to try to resolve it, the resolver will work off the (first) URL
|
||||
* returned by {@code getResource("com/mycompany");}. If this base package
|
||||
* node exists in multiple classloader locations, the actual end resource may
|
||||
* not be underneath. Therefore, preferably, use "{@code classpath*:}" with the same
|
||||
@@ -171,10 +176,10 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
private static Method equinoxResolveMethod;
|
||||
|
||||
static {
|
||||
// Detect Equinox OSGi (e.g. on WebSphere 6.1)
|
||||
try {
|
||||
Class<?> fileLocatorClass = PathMatchingResourcePatternResolver.class.getClassLoader().loadClass(
|
||||
"org.eclipse.core.runtime.FileLocator");
|
||||
// Detect Equinox OSGi (e.g. on WebSphere 6.1)
|
||||
Class<?> fileLocatorClass = ClassUtils.forName("org.eclipse.core.runtime.FileLocator",
|
||||
PathMatchingResourcePatternResolver.class.getClassLoader());
|
||||
equinoxResolveMethod = fileLocatorClass.getMethod("resolve", URL.class);
|
||||
logger.debug("Found Equinox FileLocator for OSGi bundle URL resolution");
|
||||
}
|
||||
@@ -198,17 +203,6 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
this.resourceLoader = new DefaultResourceLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.
|
||||
* @param classLoader the ClassLoader to load classpath resources with,
|
||||
* or {@code null} for using the thread context class loader
|
||||
* at the time of actual resource access
|
||||
* @see org.springframework.core.io.DefaultResourceLoader
|
||||
*/
|
||||
public PathMatchingResourcePatternResolver(ClassLoader classLoader) {
|
||||
this.resourceLoader = new DefaultResourceLoader(classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PathMatchingResourcePatternResolver.
|
||||
* <p>ClassLoader access will happen via the thread context class loader.
|
||||
@@ -220,6 +214,18 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.
|
||||
* @param classLoader the ClassLoader to load classpath resources with,
|
||||
* or {@code null} for using the thread context class loader
|
||||
* at the time of actual resource access
|
||||
* @see org.springframework.core.io.DefaultResourceLoader
|
||||
*/
|
||||
public PathMatchingResourcePatternResolver(ClassLoader classLoader) {
|
||||
this.resourceLoader = new DefaultResourceLoader(classLoader);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the ResourceLoader that this pattern resolver works with.
|
||||
*/
|
||||
@@ -227,11 +233,6 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
return this.resourceLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassLoader that this pattern resolver works with
|
||||
* (only {@code null} if even the system ClassLoader isn't accessible).
|
||||
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
||||
*/
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return getResourceLoader().getClassLoader();
|
||||
|
||||
@@ -174,9 +174,9 @@ public abstract class PropertiesLoaderUtils {
|
||||
if (classLoaderToUse == null) {
|
||||
classLoaderToUse = ClassUtils.getDefaultClassLoader();
|
||||
}
|
||||
Properties props = new Properties();
|
||||
Enumeration<URL> urls = (classLoaderToUse != null ? classLoaderToUse.getResources(resourceName) :
|
||||
ClassLoader.getSystemResources(resourceName));
|
||||
Properties props = new Properties();
|
||||
while (urls.hasMoreElements()) {
|
||||
URL url = urls.nextElement();
|
||||
URLConnection con = url.openConnection();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,9 +86,9 @@ public abstract class SpringFactoriesLoader {
|
||||
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
|
||||
String factoryClassName = factoryClass.getName();
|
||||
try {
|
||||
List<String> result = new ArrayList<String>();
|
||||
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
|
||||
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
|
||||
List<String> result = new ArrayList<String>();
|
||||
while (urls.hasMoreElements()) {
|
||||
URL url = urls.nextElement();
|
||||
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.lang.annotation.Inherited;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* A simple filter which matches classes with a given annotation,
|
||||
@@ -97,14 +98,14 @@ public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter
|
||||
if (Object.class.getName().equals(typeName)) {
|
||||
return false;
|
||||
}
|
||||
else if (typeName.startsWith("java.")) {
|
||||
else if (typeName.startsWith("java")) {
|
||||
try {
|
||||
Class<?> clazz = getClass().getClassLoader().loadClass(typeName);
|
||||
Class<?> clazz = ClassUtils.forName(typeName, getClass().getClassLoader());
|
||||
return ((this.considerMetaAnnotations ? AnnotationUtils.getAnnotation(clazz, this.annotationType) :
|
||||
clazz.getAnnotation(this.annotationType)) != null);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't determine a match that way.
|
||||
catch (Throwable ex) {
|
||||
// Class not regularly loadable - can't determine a match that way.
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.core.type.filter;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* A simple filter which matches classes that are assignable to a given type.
|
||||
*
|
||||
@@ -61,13 +63,13 @@ public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter
|
||||
else if (Object.class.getName().equals(typeName)) {
|
||||
return false;
|
||||
}
|
||||
else if (typeName.startsWith("java.")) {
|
||||
else if (typeName.startsWith("java")) {
|
||||
try {
|
||||
Class<?> clazz = getClass().getClassLoader().loadClass(typeName);
|
||||
Class<?> clazz = ClassUtils.forName(typeName, getClass().getClassLoader());
|
||||
return this.targetType.isAssignableFrom(clazz);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't determine a match that way.
|
||||
catch (Throwable ex) {
|
||||
// Class not regularly loadable - can't determine a match that way.
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user