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

@ -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.
@ -289,15 +289,15 @@ class TypeConverterDelegate {
if (index > - 1) {
String enumType = trimmedValue.substring(0, index);
String fieldName = trimmedValue.substring(index + 1);
ClassLoader loader = this.targetObject.getClass().getClassLoader();
ClassLoader cl = this.targetObject.getClass().getClassLoader();
try {
Class<?> enumValueType = loader.loadClass(enumType);
Class<?> enumValueType = ClassUtils.forName(enumType, cl);
Field enumField = enumValueType.getField(fieldName);
convertedValue = enumField.get(null);
}
catch (ClassNotFoundException ex) {
if(logger.isTraceEnabled()) {
logger.trace("Enum class [" + enumType + "] cannot be loaded from [" + loader + "]", ex);
logger.trace("Enum class [" + enumType + "] cannot be loaded", ex);
}
}
catch (Throwable ex) {

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.
@ -135,9 +135,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {

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.
@ -66,9 +66,9 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
@SuppressWarnings("unchecked")
public QualifierAnnotationAutowireCandidateResolver() {
this.qualifierTypes.add(Qualifier.class);
ClassLoader cl = QualifierAnnotationAutowireCandidateResolver.class.getClassLoader();
try {
this.qualifierTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Qualifier"));
this.qualifierTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Qualifier", QualifierAnnotationAutowireCandidateResolver.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.

View File

@ -107,9 +107,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
private static Class<?> javaxInjectProviderClass = null;
static {
ClassLoader cl = DefaultListableBeanFactory.class.getClassLoader();
try {
javaxInjectProviderClass = cl.loadClass("javax.inject.Provider");
javaxInjectProviderClass =
ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - Provider interface simply not supported then.

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.
@ -69,7 +69,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
static {
try {
closeableInterface = DisposableBeanAdapter.class.getClassLoader().loadClass("java.lang.AutoCloseable");
closeableInterface = ClassUtils.forName("java.lang.AutoCloseable",
DisposableBeanAdapter.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
closeableInterface = Closeable.class;

View File

@ -281,8 +281,8 @@ public class AnnotationConfigUtils {
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
ClassLoader cl = AnnotationConfigUtils.class.getClassLoader();
def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME));
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(

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.
@ -238,7 +238,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false));
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
@ -246,7 +246,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.inject.Named")), false));
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {

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.
@ -142,10 +142,10 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private static Class<? extends Annotation> ejbRefClass = null;
static {
ClassLoader cl = CommonAnnotationBeanPostProcessor.class.getClassLoader();
try {
@SuppressWarnings("unchecked")
Class<? extends Annotation> clazz = (Class<? extends Annotation>) cl.loadClass("javax.xml.ws.WebServiceRef");
Class<? extends Annotation> clazz = (Class<? extends Annotation>)
ClassUtils.forName("javax.xml.ws.WebServiceRef", CommonAnnotationBeanPostProcessor.class.getClassLoader());
webServiceRefClass = clazz;
}
catch (ClassNotFoundException ex) {
@ -153,7 +153,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
try {
@SuppressWarnings("unchecked")
Class<? extends Annotation> clazz = (Class<? extends Annotation>) cl.loadClass("javax.ejb.EJB");
Class<? extends Annotation> clazz = (Class<? extends Annotation>)
ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
ejbRefClass = clazz;
}
catch (ClassNotFoundException ex) {

View File

@ -34,6 +34,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Advisor that activates asynchronous method execution through the {@link Async}
@ -79,9 +80,9 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
public AsyncAnnotationAdvisor(Executor executor, AsyncUncaughtExceptionHandler exceptionHandler) {
Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<Class<? extends Annotation>>(2);
asyncAnnotationTypes.add(Async.class);
ClassLoader cl = AsyncAnnotationAdvisor.class.getClassLoader();
try {
asyncAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.ejb.Asynchronous"));
asyncAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// If EJB 3.1 API not present, simply ignore.

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;

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.
@ -98,7 +98,7 @@ public class StandardTypeLocator implements TypeLocator {
public Class<?> findType(String typeName) throws EvaluationException {
String nameToLookup = typeName;
try {
return this.classLoader.loadClass(nameToLookup);
return ClassUtils.forName(nameToLookup, this.classLoader);
}
catch (ClassNotFoundException ey) {
// try any registered prefixes before giving up
@ -106,7 +106,7 @@ public class StandardTypeLocator implements TypeLocator {
for (String prefix : this.knownPackagePrefixes) {
try {
nameToLookup = prefix + "." + typeName;
return this.classLoader.loadClass(nameToLookup);
return ClassUtils.forName(nameToLookup, this.classLoader);
}
catch (ClassNotFoundException ex) {
// might be a different prefix

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@ -18,7 +18,6 @@ package org.springframework.jdbc.core;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
@ -26,6 +25,7 @@ import javax.sql.rowset.RowSetProvider;
import org.springframework.core.JdkVersion;
import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.util.ClassUtils;
/**
* {@link ResultSetExtractor} implementation that returns a Spring {@link SqlRowSet}
@ -134,12 +134,14 @@ public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet
*/
private static class SunCachedRowSetFactory implements CachedRowSetFactory {
private static final Class<?> IMPLEMENTATION_CLASS;
private static final Class<?> implementationClass;
static {
try {
IMPLEMENTATION_CLASS = Class.forName("com.sun.rowset.CachedRowSetImpl");
implementationClass = ClassUtils.forName("com.sun.rowset.CachedRowSetImpl",
SqlRowSetResultSetExtractor.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
catch (Throwable ex) {
throw new IllegalStateException(ex);
}
}
@ -147,12 +149,9 @@ public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet
@Override
public CachedRowSet createCachedRowSet() throws SQLException {
try {
return (CachedRowSet) IMPLEMENTATION_CLASS.newInstance();
return (CachedRowSet) implementationClass.newInstance();
}
catch (InstantiationException ex) {
throw new IllegalStateException(ex);
}
catch (IllegalAccessException ex) {
catch (Throwable ex) {
throw new IllegalStateException(ex);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@ -56,9 +56,10 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
lookupDefaultSchema(databaseMetaData);
}
@Override
protected String getDefaultSchema() {
if (defaultSchema != null) {
if (this.defaultSchema != null) {
return defaultSchema;
}
return super.getDefaultSchema();
@ -81,7 +82,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
}
boolean isOracleCon;
try {
Class<?> oracleConClass = getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection");
Class<?> oracleConClass = con.getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection");
isOracleCon = oracleConClass.isInstance(con);
}
catch (ClassNotFoundException ex) {
@ -107,7 +108,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
ReflectionUtils.makeAccessible(getIncludeSynonyms);
originalValueForIncludeSynonyms = (Boolean) getIncludeSynonyms.invoke(con);
setIncludeSynonyms = con.getClass().getMethod("setIncludeSynonyms", new Class<?>[] {boolean.class});
setIncludeSynonyms = con.getClass().getMethod("setIncludeSynonyms", boolean.class);
ReflectionUtils.makeAccessible(setIncludeSynonyms);
setIncludeSynonyms.invoke(con, Boolean.TRUE);
}
@ -126,8 +127,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
}
/*
* Oracle implementation for detecting current schema
*
* Oracle-based implementation for detecting the current schema.
* @param databaseMetaData
*/
private void lookupDefaultSchema(DatabaseMetaData databaseMetaData) {
@ -144,7 +144,9 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
cstmt.close();
}
}
} catch (Exception ignore) {}
}
catch (Exception ignore) {
}
}
}

View File

@ -23,6 +23,7 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
@ -96,8 +97,7 @@ public class TestContextManager {
* @see #registerTestExecutionListeners(List)
*/
public TestContextManager(Class<?> testClass) {
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = new DefaultCacheAwareContextLoaderDelegate(
contextCache);
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = new DefaultCacheAwareContextLoaderDelegate(contextCache);
BootstrapContext bootstrapContext = new DefaultBootstrapContext(testClass, cacheAwareContextLoaderDelegate);
this.testContextBootstrapper = BootstrapUtils.resolveTestContextBootstrapper(bootstrapContext);
this.testContext = new DefaultTestContext(testContextBootstrapper);
@ -148,8 +148,7 @@ public class TestContextManager {
* registered for this {@code TestContextManager} in reverse order.
*/
private List<TestExecutionListener> getReversedTestExecutionListeners() {
List<TestExecutionListener> listenersReversed = new ArrayList<TestExecutionListener>(
getTestExecutionListeners());
List<TestExecutionListener> listenersReversed = new ArrayList<TestExecutionListener>(getTestExecutionListeners());
Collections.reverse(listenersReversed);
return listenersReversed;
}
@ -168,7 +167,7 @@ public class TestContextManager {
* @see #getTestExecutionListeners()
*/
public void beforeTestClass() throws Exception {
final Class<?> testClass = getTestContext().getTestClass();
Class<?> testClass = getTestContext().getTestClass();
if (logger.isTraceEnabled()) {
logger.trace("beforeTestClass(): class [" + testClass + "]");
}
@ -179,8 +178,8 @@ public class TestContextManager {
testExecutionListener.beforeTestClass(getTestContext());
}
catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to process 'before class' callback for test class [" + testClass + "]", ex);
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to process 'before class' callback for test class [" + testClass + "]", ex);
throw ex;
}
}
@ -212,8 +211,8 @@ public class TestContextManager {
testExecutionListener.prepareTestInstance(getTestContext());
}
catch (Exception ex) {
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to prepare test instance [" + testInstance + "]", ex);
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to prepare test instance [" + testInstance + "]", ex);
throw ex;
}
}
@ -249,9 +248,9 @@ public class TestContextManager {
testExecutionListener.beforeTestMethod(getTestContext());
}
catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to process 'before' execution of test method [" + testMethod + "] for test instance ["
+ testInstance + "]", ex);
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to process 'before' execution of test method [" + testMethod + "] for test instance [" +
testInstance + "]", ex);
throw ex;
}
}
@ -297,9 +296,9 @@ public class TestContextManager {
testExecutionListener.afterTestMethod(getTestContext());
}
catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to process 'after' execution for test: method [" + testMethod + "], instance ["
+ testInstance + "], exception [" + exception + "]", ex);
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to process 'after' execution for test: method [" + testMethod + "], instance [" +
testInstance + "], exception [" + exception + "]", ex);
if (afterTestMethodException == null) {
afterTestMethodException = ex;
}
@ -325,7 +324,7 @@ public class TestContextManager {
* @see #getTestExecutionListeners()
*/
public void afterTestClass() throws Exception {
final Class<?> testClass = getTestContext().getTestClass();
Class<?> testClass = getTestContext().getTestClass();
if (logger.isTraceEnabled()) {
logger.trace("afterTestClass(): class [" + testClass + "]");
}
@ -339,8 +338,8 @@ public class TestContextManager {
testExecutionListener.afterTestClass(getTestContext());
}
catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to process 'after class' callback for test class [" + testClass + "]", ex);
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to process 'after class' callback for test class [" + testClass + "]", ex);
if (afterTestClassException == null) {
afterTestClassException = ex;
}

View File

@ -26,6 +26,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
@ -122,8 +123,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
Class<? extends TestExecutionListener>[] listenerClasses = (Class<? extends TestExecutionListener>[]) annAttrs.getClassArray("listeners");
if (!ObjectUtils.isEmpty(valueListenerClasses) && !ObjectUtils.isEmpty(listenerClasses)) {
String msg = String.format(
"Class [%s] has been configured with @TestExecutionListeners' 'value' [%s] "
+ "and 'listeners' [%s] attributes. Use one or the other, but not both.",
"Class [%s] has been configured with @TestExecutionListeners' 'value' [%s] " +
"and 'listeners' [%s] attributes. Use one or the other, but not both.",
declaringClass, ObjectUtils.nullSafeToString(valueListenerClasses),
ObjectUtils.nullSafeToString(listenerClasses));
logger.error(msg);
@ -149,9 +150,9 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
}
catch (NoClassDefFoundError err) {
if (logger.isInfoEnabled()) {
logger.info(String.format("Could not instantiate TestExecutionListener [%s]. "
+ "Specify custom listener classes or make the default listener classes "
+ "(and their dependencies) available.", listenerClass.getName()));
logger.info(String.format("Could not instantiate TestExecutionListener [%s]. " +
"Specify custom listener classes or make the default listener classes " +
"(and their dependencies) available.", listenerClass.getName()));
}
}
}
@ -169,15 +170,15 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
@SuppressWarnings("unchecked")
protected Set<Class<? extends TestExecutionListener>> getDefaultTestExecutionListenerClasses() {
Set<Class<? extends TestExecutionListener>> defaultListenerClasses = new LinkedHashSet<Class<? extends TestExecutionListener>>();
ClassLoader cl = getClass().getClassLoader();
for (String className : getDefaultTestExecutionListenerClassNames()) {
try {
defaultListenerClasses.add((Class<? extends TestExecutionListener>) getClass().getClassLoader().loadClass(
className));
defaultListenerClasses.add((Class<? extends TestExecutionListener>) ClassUtils.forName(className, cl));
}
catch (Throwable t) {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not load default TestExecutionListener class [" + className
+ "]. Specify custom listener classes or make the default listener classes available.", t);
logger.debug("Could not load default TestExecutionListener class [" + className +
"]. Specify custom listener classes or make the default listener classes available.", ex);
}
}
}
@ -187,7 +188,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
@SuppressWarnings("unchecked")
@Override
public final MergedContextConfiguration buildMergedContextConfiguration() {
Class<?> testClass = getBootstrapContext().getTestClass();
@ -238,7 +239,6 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
* Build the {@link MergedContextConfiguration merged context configuration}
* for the supplied {@link Class testClass}, context configuration attributes,
* and parent context configuration.
*
* @param testClass the test class for which the {@code MergedContextConfiguration}
* should be built (must not be {@code null})
* @param configAttributesList the list of context configuration attributes for the
@ -303,13 +303,11 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
* Resolve the {@link ContextLoader} {@linkplain Class class} to use for the
* supplied list of {@link ContextConfigurationAttributes} and then instantiate
* and return that {@code ContextLoader}.
*
* <p>If the user has not explicitly declared which loader to use, the value
* returned from {@link #getDefaultContextLoaderClass} will be used as the
* default context loader class. For details on the class resolution process,
* see {@link #resolveExplicitContextLoaderClass} and
* {@link #getDefaultContextLoaderClass}.
*
* @param testClass the test class for which the {@code ContextLoader} should be
* resolved; must not be {@code null}
* @param configAttributesList the list of configuration attributes to process; must
@ -320,6 +318,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
*/
private ContextLoader resolveContextLoader(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributesList) {
Assert.notNull(testClass, "Class must not be null");
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be empty");
@ -327,21 +326,17 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
if (contextLoaderClass == null) {
contextLoaderClass = getDefaultContextLoaderClass(testClass);
}
if (logger.isTraceEnabled()) {
logger.trace(String.format("Using ContextLoader class [%s] for test class [%s]",
contextLoaderClass.getName(), testClass.getName()));
}
return BeanUtils.instantiateClass(contextLoaderClass, ContextLoader.class);
}
/**
* Resolve the {@link ContextLoader} {@linkplain Class class} to use for the supplied
* list of {@link ContextConfigurationAttributes}.
*
* <p>Beginning with the first level in the context configuration attributes hierarchy:
*
* <ol>
* <li>If the {@link ContextConfigurationAttributes#getContextLoaderClass()
* contextLoaderClass} property of {@link ContextConfigurationAttributes} is
@ -350,7 +345,6 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
* level in the hierarchy, traverse to the next level in the hierarchy and return to
* step #1.</li>
* </ol>
*
* @param configAttributesList the list of configuration attributes to process;
* must not be {@code null} or <em>empty</em>; must be ordered <em>bottom-up</em>
* (i.e., as if we were traversing up the class hierarchy)
@ -361,14 +355,13 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
*/
private Class<? extends ContextLoader> resolveExplicitContextLoaderClass(
List<ContextConfigurationAttributes> configAttributesList) {
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be empty");
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be empty");
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
if (logger.isTraceEnabled()) {
logger.trace(String.format("Resolving ContextLoader for context configuration attributes %s",
configAttributes));
}
Class<? extends ContextLoader> contextLoaderClass = configAttributes.getContextLoaderClass();
if (!ContextLoader.class.equals(contextLoaderClass)) {
if (logger.isDebugEnabled()) {
@ -379,7 +372,6 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
return contextLoaderClass;
}
}
return null;
}
@ -405,12 +397,10 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
/**
* Build a {@link MergedContextConfiguration} instance from the supplied,
* merged values.
*
* <p>Concrete subclasses typically will only need to instantiate
* {@link MergedContextConfiguration} (or a specialized subclass thereof)
* from the provided values; further processing and merging of values is likely
* unnecessary.
*
* @param testClass the test class for which the {@code MergedContextConfiguration}
* should be built (must not be {@code null})
* @param locations the merged resource locations
@ -425,9 +415,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
* @return the fully initialized {@code MergedContextConfiguration}
*/
protected abstract MergedContextConfiguration buildMergedContextConfiguration(
Class<?> testClass,
String[] locations,
Class<?>[] classes,
Class<?> testClass, String[] locations, Class<?>[] classes,
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses,
String[] activeProfiles, ContextLoader contextLoader,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parentConfig);

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.
@ -35,6 +35,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
@ -50,7 +51,6 @@ import org.springframework.util.ReflectionUtils;
*
* @author Rossen Stoyanchev
* @since 4.0
*
* @see ServerEndpointRegistration
* @see SpringConfigurator
* @see ServletServerContainerFactoryBean
@ -97,9 +97,9 @@ public class ServerEndpointExporter implements InitializingBean, BeanPostProcess
protected ServerContainer getServerContainer() {
Class<?> servletContextClass;
try {
servletContextClass = Class.forName("javax.servlet.ServletContext");
servletContextClass = ClassUtils.forName("javax.servlet.ServletContext", getClass().getClassLoader());
}
catch (Throwable e) {
catch (Throwable ex) {
return null;
}
@ -139,8 +139,8 @@ public class ServerEndpointExporter implements InitializingBean, BeanPostProcess
ServerEndpointConfig sec = (ServerEndpointConfig) bean;
try {
if (logger.isInfoEnabled()) {
logger.info("Registering bean '" + beanName
+ "' as javax.websocket.Endpoint under path " + sec.getPath());
logger.info("Registering bean '" + beanName +
"' as javax.websocket.Endpoint under path " + sec.getPath());
}
getServerContainer().addEndpoint(sec);
}