General defensiveness about the bootstrap ClassLoader (i.e. null ClassLoader)

Issue: SPR-11721
(cherry picked from commit 59cef3c)
This commit is contained in:
Juergen Hoeller
2014-04-28 00:26:18 +02:00
parent ce1954da1e
commit 6cb45f714e
20 changed files with 124 additions and 129 deletions

View File

@@ -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/**&#47;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();

View File

@@ -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();

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;