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

Issue: SPR-11721
This commit is contained in:
Juergen Hoeller
2014-04-23 23:54:55 +02:00
parent 2c1203dc9f
commit 9e2060707a
30 changed files with 230 additions and 180 deletions

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.
@@ -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.
@@ -71,9 +71,9 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
@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

@@ -103,9 +103,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

@@ -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.
@@ -34,6 +34,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.Constants;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -259,7 +260,7 @@ public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNam
Class<?> cronTriggerClass;
Method jobKeyMethod;
try {
cronTriggerClass = getClass().getClassLoader().loadClass("org.quartz.impl.triggers.CronTriggerImpl");
cronTriggerClass = ClassUtils.forName("org.quartz.impl.triggers.CronTriggerImpl", getClass().getClassLoader());
jobKeyMethod = JobDetail.class.getMethod("getKey");
}
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.
@@ -30,6 +30,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ClassUtils;
/**
* A Spring {@link FactoryBean} for creating a Quartz {@link org.quartz.JobDetail}
@@ -56,7 +57,7 @@ public class JobDetailFactoryBean
private String group;
private Class jobClass;
private Class<?> jobClass;
private JobDataMap jobDataMap = new JobDataMap();
@@ -92,7 +93,7 @@ public class JobDetailFactoryBean
/**
* Specify the job's implementation class.
*/
public void setJobClass(Class jobClass) {
public void setJobClass(Class<?> jobClass) {
this.jobClass = jobClass;
}
@@ -207,7 +208,7 @@ public class JobDetailFactoryBean
Class<?> jobDetailClass;
try {
jobDetailClass = getClass().getClassLoader().loadClass("org.quartz.impl.JobDetailImpl");
jobDetailClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl", getClass().getClassLoader());
}
catch (ClassNotFoundException ex) {
jobDetailClass = JobDetail.class;

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,14 +86,15 @@ public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethod
static {
try {
jobDetailImplClass = Class.forName("org.quartz.impl.JobDetailImpl");
jobDetailImplClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl",
MethodInvokingJobDetailFactoryBean.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
jobDetailImplClass = null;
}
try {
Class<?> jobExecutionContextClass =
QuartzJobBean.class.getClassLoader().loadClass("org.quartz.JobExecutionContext");
Class<?> jobExecutionContextClass = ClassUtils.forName("org.quartz.JobExecutionContext",
MethodInvokingJobDetailFactoryBean.class.getClassLoader());
setResultMethod = jobExecutionContextClass.getMethod("setResult", Object.class);
}
catch (Exception 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.
@@ -28,6 +28,7 @@ import org.quartz.SchedulerException;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -79,8 +80,8 @@ public abstract class QuartzJobBean implements Job {
static {
try {
Class jobExecutionContextClass =
QuartzJobBean.class.getClassLoader().loadClass("org.quartz.JobExecutionContext");
Class<?> jobExecutionContextClass =
ClassUtils.forName("org.quartz.JobExecutionContext", QuartzJobBean.class.getClassLoader());
getSchedulerMethod = jobExecutionContextClass.getMethod("getScheduler");
getMergedJobDataMapMethod = jobExecutionContextClass.getMethod("getMergedJobDataMap");
}
@@ -99,7 +100,7 @@ public abstract class QuartzJobBean implements Job {
try {
// Reflectively adapting to differences between Quartz 1.x and Quartz 2.0...
Scheduler scheduler = (Scheduler) ReflectionUtils.invokeMethod(getSchedulerMethod, context);
Map mergedJobDataMap = (Map) ReflectionUtils.invokeMethod(getMergedJobDataMapMethod, context);
Map<?, ?> mergedJobDataMap = (Map<?, ?>) ReflectionUtils.invokeMethod(getMergedJobDataMapMethod, context);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
MutablePropertyValues pvs = new MutablePropertyValues();

View File

@@ -42,6 +42,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -66,8 +67,8 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
static {
// Quartz 2.0 job/trigger key available?
try {
jobKeyClass = Class.forName("org.quartz.JobKey");
triggerKeyClass = Class.forName("org.quartz.TriggerKey");
jobKeyClass = ClassUtils.forName("org.quartz.JobKey", SchedulerAccessor.class.getClassLoader());
triggerKeyClass = ClassUtils.forName("org.quartz.TriggerKey", SchedulerAccessor.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
jobKeyClass = null;
@@ -254,7 +255,7 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
clh.initialize();
try {
// Quartz 1.8 or higher?
Class<?> dataProcessorClass = getClass().getClassLoader().loadClass("org.quartz.xml.XMLSchedulingDataProcessor");
Class<?> dataProcessorClass = ClassUtils.forName("org.quartz.xml.XMLSchedulingDataProcessor", getClass().getClassLoader());
logger.debug("Using Quartz 1.8 XMLSchedulingDataProcessor");
Object dataProcessor = dataProcessorClass.getConstructor(ClassLoadHelper.class).newInstance(clh);
Method processFileAndScheduleJobs = dataProcessorClass.getMethod("processFileAndScheduleJobs", String.class, Scheduler.class);
@@ -264,7 +265,7 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
}
catch (ClassNotFoundException ex) {
// Quartz 1.6
Class<?> dataProcessorClass = getClass().getClassLoader().loadClass("org.quartz.xml.JobSchedulingDataProcessor");
Class<?> dataProcessorClass = ClassUtils.forName("org.quartz.xml.JobSchedulingDataProcessor", getClass().getClassLoader());
logger.debug("Using Quartz 1.6 JobSchedulingDataProcessor");
Object dataProcessor = dataProcessorClass.getConstructor(ClassLoadHelper.class, boolean.class, boolean.class).newInstance(clh, true, true);
Method processFileAndScheduleJobs = dataProcessorClass.getMethod("processFileAndScheduleJobs", String.class, Scheduler.class, boolean.class);

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.
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.Constants;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -250,7 +251,7 @@ public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, Bea
Class<?> simpleTriggerClass;
Method jobKeyMethod;
try {
simpleTriggerClass = getClass().getClassLoader().loadClass("org.quartz.impl.triggers.SimpleTriggerImpl");
simpleTriggerClass = ClassUtils.forName("org.quartz.impl.triggers.SimpleTriggerImpl", getClass().getClassLoader());
jobKeyMethod = JobDetail.class.getMethod("getKey");
}
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.
@@ -208,8 +208,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.
@@ -227,7 +227,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) {
@@ -235,7 +235,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.
@@ -145,10 +145,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) {
@@ -156,7 +156,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

@@ -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.
@@ -32,6 +32,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}
@@ -73,9 +74,9 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
public AsyncAnnotationAdvisor(Executor executor) {
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

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 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.
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.JdkVersion;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@@ -74,7 +75,7 @@ public class TaskExecutorFactoryBean implements
public void afterPropertiesSet() throws Exception {
Class<?> executorClass = (shouldUseBackport() ?
getClass().getClassLoader().loadClass("org.springframework.scheduling.backportconcurrent.ThreadPoolTaskExecutor") :
ClassUtils.forName("org.springframework.scheduling.backportconcurrent.ThreadPoolTaskExecutor", getClass().getClassLoader()) :
ThreadPoolTaskExecutor.class);
BeanWrapper bw = new BeanWrapperImpl(executorClass);
determinePoolSizeRange(bw);

View File

@@ -34,6 +34,7 @@ import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -73,8 +74,8 @@ public abstract class CollectionFactory {
// New Java 6 collection interfaces
ClassLoader cl = CollectionFactory.class.getClassLoader();
try {
navigableSetClass = cl.loadClass("java.util.NavigableSet");
navigableMapClass = cl.loadClass("java.util.NavigableMap");
navigableSetClass = ClassUtils.forName("java.util.NavigableSet", cl);
navigableMapClass = ClassUtils.forName("java.util.NavigableMap", cl);
approximableCollectionTypes.add(navigableSetClass);
approximableMapTypes.add(navigableMapClass);
}

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.
@@ -50,9 +50,9 @@ public class ClassPathResource extends AbstractFileResolvingResource {
/**
* Create a new ClassPathResource for ClassLoader usage.
* A leading slash will be removed, as the ClassLoader
* resource access methods will not accept it.
* Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
* A leading slash will be removed, as the ClassLoader resource access
* methods will not accept it.
* <p>The thread context class loader will be used for
* loading the resource.
* @param path the absolute path within the class path
@@ -64,9 +64,9 @@ public class ClassPathResource extends AbstractFileResolvingResource {
}
/**
* Create a new ClassPathResource for ClassLoader usage.
* A leading slash will be removed, as the ClassLoader
* resource access methods will not accept it.
* Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
* A leading slash will be removed, as the ClassLoader resource access
* methods will not accept it.
* @param path the absolute path within the classpath
* @param classLoader the class loader to load the resource with,
* or {@code null} for the thread context class loader
@@ -83,9 +83,9 @@ public class ClassPathResource extends AbstractFileResolvingResource {
}
/**
* Create a new ClassPathResource for Class usage.
* The path can be relative to the given class,
* or absolute within the classpath via a leading slash.
* Create a new {@code ClassPathResource} for {@code Class} usage.
* The path can be relative to the given class, or absolute within
* the classpath via a leading slash.
* @param path relative or absolute path within the class path
* @param clazz the class to load resources with
* @see java.lang.Class#getResourceAsStream
@@ -97,8 +97,8 @@ public class ClassPathResource extends AbstractFileResolvingResource {
}
/**
* Create a new ClassPathResource with optional ClassLoader and Class.
* Only for internal usage.
* Create a new {@code ClassPathResource} with optional {@code ClassLoader}
* and {@code Class}. Only for internal usage.
* @param path relative or absolute path within the classpath
* @param classLoader the class loader to load the resource with, if any
* @param clazz the class to load resources with, if any
@@ -109,6 +109,7 @@ public class ClassPathResource extends AbstractFileResolvingResource {
this.clazz = clazz;
}
/**
* Return the path for this resource (as resource path within the class path).
*/
@@ -120,9 +121,10 @@ public class ClassPathResource extends AbstractFileResolvingResource {
* Return the ClassLoader that this resource will be obtained from.
*/
public final ClassLoader getClassLoader() {
return (this.classLoader != null ? this.classLoader : this.clazz.getClassLoader());
return (this.clazz != null ? this.clazz.getClassLoader() : this.classLoader);
}
/**
* This implementation checks for the resolution of a resource URL.
* @see java.lang.ClassLoader#getResource(String)
@@ -130,14 +132,23 @@ public class ClassPathResource extends AbstractFileResolvingResource {
*/
@Override
public boolean exists() {
URL url;
return (resolveURL() != null);
}
/**
* Resolves a URL for the underlying class path resource.
* @return the resolved URL, or {@code null} if not resolvable
*/
protected URL resolveURL() {
if (this.clazz != null) {
url = this.clazz.getResource(this.path);
return this.clazz.getResource(this.path);
}
else if (this.classLoader != null) {
return this.classLoader.getResource(this.path);
}
else {
url = this.classLoader.getResource(this.path);
return ClassLoader.getSystemResource(this.path);
}
return (url != null);
}
/**
@@ -150,9 +161,12 @@ public class ClassPathResource extends AbstractFileResolvingResource {
if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
}
else {
else if (this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
}
else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if (is == null) {
throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
}
@@ -160,19 +174,14 @@ public class ClassPathResource extends AbstractFileResolvingResource {
}
/**
* This implementation returns a URL for the underlying class path resource.
* This implementation returns a URL for the underlying class path resource,
* if available.
* @see java.lang.ClassLoader#getResource(String)
* @see java.lang.Class#getResource(String)
*/
@Override
public URL getURL() throws IOException {
URL url;
if (this.clazz != null) {
url = this.clazz.getResource(this.path);
}
else {
url = this.classLoader.getResource(this.path);
}
URL url = resolveURL();
if (url == null) {
throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist");
}

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.
@@ -70,7 +70,9 @@ public interface ResourceLoader {
* <p>Clients which need to access the ClassLoader directly can do so
* in a uniform manner with the ResourceLoader, rather than relying
* on the thread context ClassLoader.
* @return the ClassLoader (never {@code null})
* @return the ClassLoader (only {@code null} if even the system
* ClassLoader isn't accessible)
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
*/
ClassLoader getClassLoader();

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.
@@ -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;
@@ -72,7 +73,7 @@ import org.springframework.util.StringUtils;
* <p><b>Ant-style Patterns:</b>
*
* <p>When the path location contains an Ant-style pattern, e.g.:
* <pre>
* <pre class="code">
* /WEB-INF/*-context.xml
* com/mycompany/**&#47;applicationContext.xml
* file:C:/some/path/*-context.xml
@@ -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>
* 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>
* </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,10 +233,6 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
return this.resourceLoader;
}
/**
* Return the ClassLoader that this pattern resolver works with
* (never {@code null}).
*/
public ClassLoader getClassLoader() {
return getResourceLoader().getClassLoader();
}
@@ -298,7 +300,8 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
if (path.startsWith("/")) {
path = path.substring(1);
}
Enumeration<URL> resourceUrls = getClassLoader().getResources(path);
ClassLoader cl = getClassLoader();
Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
Set<Resource> result = new LinkedHashSet<Resource>(16);
while (resourceUrls.hasMoreElements()) {
URL url = resourceUrls.nextElement();

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.
@@ -170,14 +170,15 @@ public abstract class PropertiesLoaderUtils {
*/
public static Properties loadAllProperties(String resourceName, ClassLoader classLoader) throws IOException {
Assert.notNull(resourceName, "Resource name must not be null");
ClassLoader clToUse = classLoader;
if (clToUse == null) {
clToUse = ClassUtils.getDefaultClassLoader();
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = ClassUtils.getDefaultClassLoader();
}
Enumeration<URL> urls = (classLoaderToUse != null ? classLoaderToUse.getResources(resourceName) :
ClassLoader.getSystemResources(resourceName));
Properties props = new Properties();
Enumeration urls = clToUse.getResources(resourceName);
while (urls.hasMoreElements()) {
URL url = (URL) urls.nextElement();
URL url = urls.nextElement();
URLConnection con = url.openConnection();
ResourceUtils.useCachesIfNecessary(con);
InputStream is = con.getInputStream();

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.
@@ -67,16 +67,17 @@ public abstract class SpringFactoriesLoader {
*/
public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
Assert.notNull(factoryClass, "'factoryClass' must not be null");
if (classLoader == null) {
classLoader = SpringFactoriesLoader.class.getClassLoader();
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
List<String> factoryNames = loadFactoryNames(factoryClass, classLoader);
List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
}
List<T> result = new ArrayList<T>(factoryNames.size());
for (String factoryName : factoryNames) {
result.add(instantiateFactory(factoryName, factoryClass, classLoader));
result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
}
OrderComparator.sort(result);
return result;
@@ -85,8 +86,9 @@ public abstract class SpringFactoriesLoader {
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List<String> result = new ArrayList<String>();
Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));

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.
@@ -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.
*
@@ -26,14 +28,14 @@ package org.springframework.core.type.filter;
*/
public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter {
private final Class targetType;
private final Class<?> targetType;
/**
* Create a new AssignableTypeFilter for the given type.
* @param targetType the type to match
*/
public AssignableTypeFilter(Class targetType) {
public AssignableTypeFilter(Class<?> targetType) {
super(true, true);
this.targetType = targetType;
}
@@ -59,15 +61,15 @@ public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter
return true;
}
else if (Object.class.getName().equals(typeName)) {
return Boolean.FALSE;
return false;
}
else if (typeName.startsWith("java.")) {
else if (typeName.startsWith("java")) {
try {
Class clazz = getClass().getClassLoader().loadClass(typeName);
return Boolean.valueOf(this.targetType.isAssignableFrom(clazz));
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

@@ -142,12 +142,14 @@ public abstract class ClassUtils {
* ClassLoader, if available; the ClassLoader that loaded the ClassUtils
* class will be used as fallback.
* <p>Call this method if you intend to use the thread context ClassLoader
* in a scenario where you absolutely need a non-null ClassLoader reference:
* in a scenario where you clearly prefer a non-null ClassLoader reference:
* for example, for class path resource loading (but not necessarily for
* {@code Class.forName}, which accepts a {@code null} ClassLoader
* reference as well).
* @return the default ClassLoader (never {@code null})
* @return the default ClassLoader (only {@code null} if even the system
* ClassLoader isn't accessible)
* @see Thread#getContextClassLoader()
* @see ClassLoader#getSystemClassLoader()
*/
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
@@ -155,11 +157,20 @@ public abstract class ClassUtils {
cl = Thread.currentThread().getContextClassLoader();
}
catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back to system class loader...
// Cannot access thread context ClassLoader - falling back...
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = ClassUtils.class.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
}
catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}
@@ -247,19 +258,19 @@ public abstract class ClassUtils {
return Array.newInstance(elementClass, 0).getClass();
}
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = getDefaultClassLoader();
ClassLoader clToUse = classLoader;
if (clToUse == null) {
clToUse = getDefaultClassLoader();
}
try {
return classLoaderToUse.loadClass(name);
return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name));
}
catch (ClassNotFoundException ex) {
int lastDotIndex = name.lastIndexOf('.');
if (lastDotIndex != -1) {
String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1);
try {
return classLoaderToUse.loadClass(innerClassName);
return (clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName));
}
catch (ClassNotFoundException ex2) {
// swallow - let original exception get through

View File

@@ -119,7 +119,8 @@ public abstract class ResourceUtils {
Assert.notNull(resourceLocation, "Resource location must not be null");
if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) {
String path = resourceLocation.substring(CLASSPATH_URL_PREFIX.length());
URL url = ClassUtils.getDefaultClassLoader().getResource(path);
ClassLoader cl = ClassUtils.getDefaultClassLoader();
URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path));
if (url == null) {
String description = "class path resource [" + path + "]";
throw new FileNotFoundException(
@@ -159,7 +160,8 @@ public abstract class ResourceUtils {
if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) {
String path = resourceLocation.substring(CLASSPATH_URL_PREFIX.length());
String description = "class path resource [" + path + "]";
URL url = ClassUtils.getDefaultClassLoader().getResource(path);
ClassLoader cl = ClassUtils.getDefaultClassLoader();
URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path));
if (url == null) {
throw new FileNotFoundException(
description + " cannot be resolved to absolute file path " +

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.
@@ -97,7 +97,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
@@ -105,7 +105,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.
@@ -81,7 +81,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) {

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.
@@ -27,6 +27,7 @@ import org.hibernate.type.TypeFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -73,8 +74,8 @@ public class FilterDefinitionFactoryBean implements FactoryBean<FilterDefinition
static {
// Hibernate 3.6 TypeResolver class available?
try {
Class<?> trClass = FilterDefinitionFactoryBean.class.getClassLoader().loadClass(
"org.hibernate.type.TypeResolver");
Class<?> trClass = ClassUtils.forName("org.hibernate.type.TypeResolver",
FilterDefinitionFactoryBean.class.getClassLoader());
heuristicTypeMethod = trClass.getMethod("heuristicType", String.class);
typeResolver = trClass.newInstance();
}

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.
@@ -31,6 +31,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
@@ -154,8 +155,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;
}
@@ -188,18 +188,17 @@ public class TestContextManager {
while (declaringClass != null) {
TestExecutionListeners testExecutionListeners = declaringClass.getAnnotation(annotationType);
if (logger.isTraceEnabled()) {
logger.trace("Retrieved @TestExecutionListeners [" + testExecutionListeners
+ "] for declaring class [" + declaringClass + "].");
logger.trace("Retrieved @TestExecutionListeners [" + testExecutionListeners +
"] for declaring class [" + declaringClass + "].");
}
Class<? extends TestExecutionListener>[] valueListenerClasses = testExecutionListeners.value();
Class<? extends TestExecutionListener>[] listenerClasses = testExecutionListeners.listeners();
if (!ObjectUtils.isEmpty(valueListenerClasses) && !ObjectUtils.isEmpty(listenerClasses)) {
String msg = String.format(
"Test 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));
String msg = String.format("Test 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);
throw new IllegalStateException(msg);
} else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
@@ -221,9 +220,9 @@ public class TestContextManager {
}
catch (NoClassDefFoundError err) {
if (logger.isInfoEnabled()) {
logger.info(String.format("Could not instantiate TestExecutionListener class [%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 class [%s]. " +
"Specify custom listener classes or make the default listener classes " +
"(and their dependencies) available.", listenerClass.getName()));
}
}
}
@@ -236,14 +235,15 @@ public class TestContextManager {
@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 : DEFAULT_TEST_EXECUTION_LISTENER_CLASS_NAMES) {
try {
defaultListenerClasses.add((Class<? extends TestExecutionListener>) getClass().getClassLoader().loadClass(
className));
} catch (Throwable t) {
defaultListenerClasses.add((Class<? extends TestExecutionListener>) ClassUtils.forName(className, cl));
}
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);
}
}
}
@@ -273,9 +273,10 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
try {
testExecutionListener.beforeTestClass(getTestContext());
} catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to process 'before class' callback for test class [" + testClass + "]", ex);
}
catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to process 'before class' callback for test class [" + testClass + "]", ex);
throw ex;
}
}
@@ -305,9 +306,10 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
try {
testExecutionListener.prepareTestInstance(getTestContext());
} catch (Exception ex) {
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to prepare test instance [" + testInstance + "]", ex);
}
catch (Exception ex) {
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to prepare test instance [" + testInstance + "]", ex);
throw ex;
}
}
@@ -341,10 +343,11 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
try {
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);
}
catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to process 'before' execution of test method [" + testMethod + "] for test instance [" +
testInstance + "]", ex);
throw ex;
}
}
@@ -388,10 +391,11 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
try {
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);
}
catch (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;
}
@@ -429,9 +433,10 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
try {
testExecutionListener.afterTestClass(getTestContext());
} catch (Exception ex) {
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
+ "] to process 'after class' callback for test class [" + testClass + "]", ex);
}
catch (Exception 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

@@ -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.
@@ -50,6 +50,7 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@@ -154,9 +155,9 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
private static Class<?> transactionSynchronizationRegistryClass;
static {
ClassLoader cl = JtaTransactionManager.class.getClassLoader();
try {
transactionSynchronizationRegistryClass = cl.loadClass(TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME);
transactionSynchronizationRegistryClass = ClassUtils.forName(
TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME, JtaTransactionManager.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// JTA 1.1 API not available... simply proceed the JTA 1.0 way.