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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -289,15 +289,15 @@ class TypeConverterDelegate {
if (index > - 1) { if (index > - 1) {
String enumType = trimmedValue.substring(0, index); String enumType = trimmedValue.substring(0, index);
String fieldName = trimmedValue.substring(index + 1); String fieldName = trimmedValue.substring(index + 1);
ClassLoader loader = this.targetObject.getClass().getClassLoader(); ClassLoader cl = this.targetObject.getClass().getClassLoader();
try { try {
Class<?> enumValueType = loader.loadClass(enumType); Class<?> enumValueType = ClassUtils.forName(enumType, cl);
Field enumField = enumValueType.getField(fieldName); Field enumField = enumValueType.getField(fieldName);
convertedValue = enumField.get(null); convertedValue = enumField.get(null);
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
if(logger.isTraceEnabled()) { 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) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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() { public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class); this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class); this.autowiredAnnotationTypes.add(Value.class);
ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
try { 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"); logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
} }
catch (ClassNotFoundException ex) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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") @SuppressWarnings("unchecked")
public QualifierAnnotationAutowireCandidateResolver() { public QualifierAnnotationAutowireCandidateResolver() {
this.qualifierTypes.add(Qualifier.class); this.qualifierTypes.add(Qualifier.class);
ClassLoader cl = QualifierAnnotationAutowireCandidateResolver.class.getClassLoader();
try { 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) { catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip. // JSR-330 API not available - simply skip.

View File

@@ -103,9 +103,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
private static Class<?> javaxInjectProviderClass = null; private static Class<?> javaxInjectProviderClass = null;
static { static {
ClassLoader cl = DefaultListableBeanFactory.class.getClassLoader();
try { try {
javaxInjectProviderClass = cl.loadClass("javax.inject.Provider"); javaxInjectProviderClass =
ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
// JSR-330 API not available - Provider interface simply not supported then. // 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { static {
try { try {
closeableInterface = DisposableBeanAdapter.class.getClassLoader().loadClass("java.lang.AutoCloseable"); closeableInterface = ClassUtils.forName("java.lang.AutoCloseable",
DisposableBeanAdapter.class.getClassLoader());
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
closeableInterface = Closeable.class; 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.beans.factory.InitializingBean;
import org.springframework.core.Constants; import org.springframework.core.Constants;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@@ -259,7 +260,7 @@ public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNam
Class<?> cronTriggerClass; Class<?> cronTriggerClass;
Method jobKeyMethod; Method jobKeyMethod;
try { 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"); jobKeyMethod = JobDetail.class.getMethod("getKey");
} }
catch (ClassNotFoundException ex) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ClassUtils;
/** /**
* A Spring {@link FactoryBean} for creating a Quartz {@link org.quartz.JobDetail} * A Spring {@link FactoryBean} for creating a Quartz {@link org.quartz.JobDetail}
@@ -56,7 +57,7 @@ public class JobDetailFactoryBean
private String group; private String group;
private Class jobClass; private Class<?> jobClass;
private JobDataMap jobDataMap = new JobDataMap(); private JobDataMap jobDataMap = new JobDataMap();
@@ -92,7 +93,7 @@ public class JobDetailFactoryBean
/** /**
* Specify the job's implementation class. * Specify the job's implementation class.
*/ */
public void setJobClass(Class jobClass) { public void setJobClass(Class<?> jobClass) {
this.jobClass = jobClass; this.jobClass = jobClass;
} }
@@ -207,7 +208,7 @@ public class JobDetailFactoryBean
Class<?> jobDetailClass; Class<?> jobDetailClass;
try { try {
jobDetailClass = getClass().getClassLoader().loadClass("org.quartz.impl.JobDetailImpl"); jobDetailClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl", getClass().getClassLoader());
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
jobDetailClass = JobDetail.class; 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -86,14 +86,15 @@ public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethod
static { static {
try { try {
jobDetailImplClass = Class.forName("org.quartz.impl.JobDetailImpl"); jobDetailImplClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl",
MethodInvokingJobDetailFactoryBean.class.getClassLoader());
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
jobDetailImplClass = null; jobDetailImplClass = null;
} }
try { try {
Class<?> jobExecutionContextClass = Class<?> jobExecutionContextClass = ClassUtils.forName("org.quartz.JobExecutionContext",
QuartzJobBean.class.getClassLoader().loadClass("org.quartz.JobExecutionContext"); MethodInvokingJobDetailFactoryBean.class.getClassLoader());
setResultMethod = jobExecutionContextClass.getMethod("setResult", Object.class); setResultMethod = jobExecutionContextClass.getMethod("setResult", Object.class);
} }
catch (Exception ex) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.BeanWrapper;
import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyAccessorFactory; import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@@ -79,8 +80,8 @@ public abstract class QuartzJobBean implements Job {
static { static {
try { try {
Class jobExecutionContextClass = Class<?> jobExecutionContextClass =
QuartzJobBean.class.getClassLoader().loadClass("org.quartz.JobExecutionContext"); ClassUtils.forName("org.quartz.JobExecutionContext", QuartzJobBean.class.getClassLoader());
getSchedulerMethod = jobExecutionContextClass.getMethod("getScheduler"); getSchedulerMethod = jobExecutionContextClass.getMethod("getScheduler");
getMergedJobDataMapMethod = jobExecutionContextClass.getMethod("getMergedJobDataMap"); getMergedJobDataMapMethod = jobExecutionContextClass.getMethod("getMergedJobDataMap");
} }
@@ -99,7 +100,7 @@ public abstract class QuartzJobBean implements Job {
try { try {
// Reflectively adapting to differences between Quartz 1.x and Quartz 2.0... // Reflectively adapting to differences between Quartz 1.x and Quartz 2.0...
Scheduler scheduler = (Scheduler) ReflectionUtils.invokeMethod(getSchedulerMethod, context); 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); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
MutablePropertyValues pvs = new MutablePropertyValues(); MutablePropertyValues pvs = new MutablePropertyValues();

View File

@@ -42,6 +42,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@@ -66,8 +67,8 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
static { static {
// Quartz 2.0 job/trigger key available? // Quartz 2.0 job/trigger key available?
try { try {
jobKeyClass = Class.forName("org.quartz.JobKey"); jobKeyClass = ClassUtils.forName("org.quartz.JobKey", SchedulerAccessor.class.getClassLoader());
triggerKeyClass = Class.forName("org.quartz.TriggerKey"); triggerKeyClass = ClassUtils.forName("org.quartz.TriggerKey", SchedulerAccessor.class.getClassLoader());
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
jobKeyClass = null; jobKeyClass = null;
@@ -254,7 +255,7 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
clh.initialize(); clh.initialize();
try { try {
// Quartz 1.8 or higher? // 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"); logger.debug("Using Quartz 1.8 XMLSchedulingDataProcessor");
Object dataProcessor = dataProcessorClass.getConstructor(ClassLoadHelper.class).newInstance(clh); Object dataProcessor = dataProcessorClass.getConstructor(ClassLoadHelper.class).newInstance(clh);
Method processFileAndScheduleJobs = dataProcessorClass.getMethod("processFileAndScheduleJobs", String.class, Scheduler.class); Method processFileAndScheduleJobs = dataProcessorClass.getMethod("processFileAndScheduleJobs", String.class, Scheduler.class);
@@ -264,7 +265,7 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
// Quartz 1.6 // 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"); logger.debug("Using Quartz 1.6 JobSchedulingDataProcessor");
Object dataProcessor = dataProcessorClass.getConstructor(ClassLoadHelper.class, boolean.class, boolean.class).newInstance(clh, true, true); 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); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.beans.factory.InitializingBean;
import org.springframework.core.Constants; import org.springframework.core.Constants;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@@ -250,7 +251,7 @@ public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, Bea
Class<?> simpleTriggerClass; Class<?> simpleTriggerClass;
Method jobKeyMethod; Method jobKeyMethod;
try { 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"); jobKeyMethod = JobDetail.class.getMethod("getKey");
} }
catch (ClassNotFoundException ex) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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)) { if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(); RootBeanDefinition def = new RootBeanDefinition();
try { try {
ClassLoader cl = AnnotationConfigUtils.class.getClassLoader(); def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME)); AnnotationConfigUtils.class.getClassLoader()));
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
throw new IllegalStateException( 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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(); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try { try {
this.includeFilters.add(new AnnotationTypeFilter( 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"); logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
@@ -235,7 +235,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
} }
try { try {
this.includeFilters.add(new AnnotationTypeFilter( 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"); logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
} }
catch (ClassNotFoundException ex) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; private static Class<? extends Annotation> ejbRefClass = null;
static { static {
ClassLoader cl = CommonAnnotationBeanPostProcessor.class.getClassLoader();
try { try {
@SuppressWarnings("unchecked") @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; webServiceRefClass = clazz;
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
@@ -156,7 +156,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
} }
try { try {
@SuppressWarnings("unchecked") @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; ejbRefClass = clazz;
} }
catch (ClassNotFoundException ex) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.beans.factory.BeanFactoryAware;
import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/** /**
* Advisor that activates asynchronous method execution through the {@link Async} * 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) { public AsyncAnnotationAdvisor(Executor executor) {
Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<Class<? extends Annotation>>(2); Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<Class<? extends Annotation>>(2);
asyncAnnotationTypes.add(Async.class); asyncAnnotationTypes.add(Async.class);
ClassLoader cl = AsyncAnnotationAdvisor.class.getClassLoader();
try { 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) { catch (ClassNotFoundException ex) {
// If EJB 3.1 API not present, simply ignore. // 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.JdkVersion;
import org.springframework.core.task.TaskExecutor; import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@@ -74,7 +75,7 @@ public class TaskExecutorFactoryBean implements
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Class<?> executorClass = (shouldUseBackport() ? Class<?> executorClass = (shouldUseBackport() ?
getClass().getClassLoader().loadClass("org.springframework.scheduling.backportconcurrent.ThreadPoolTaskExecutor") : ClassUtils.forName("org.springframework.scheduling.backportconcurrent.ThreadPoolTaskExecutor", getClass().getClassLoader()) :
ThreadPoolTaskExecutor.class); ThreadPoolTaskExecutor.class);
BeanWrapper bw = new BeanWrapperImpl(executorClass); BeanWrapper bw = new BeanWrapperImpl(executorClass);
determinePoolSizeRange(bw); determinePoolSizeRange(bw);

View File

@@ -34,6 +34,7 @@ import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
@@ -73,8 +74,8 @@ public abstract class CollectionFactory {
// New Java 6 collection interfaces // New Java 6 collection interfaces
ClassLoader cl = CollectionFactory.class.getClassLoader(); ClassLoader cl = CollectionFactory.class.getClassLoader();
try { try {
navigableSetClass = cl.loadClass("java.util.NavigableSet"); navigableSetClass = ClassUtils.forName("java.util.NavigableSet", cl);
navigableMapClass = cl.loadClass("java.util.NavigableMap"); navigableMapClass = ClassUtils.forName("java.util.NavigableMap", cl);
approximableCollectionTypes.add(navigableSetClass); approximableCollectionTypes.add(navigableSetClass);
approximableMapTypes.add(navigableMapClass); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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. * Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
* A leading slash will be removed, as the ClassLoader * A leading slash will be removed, as the ClassLoader resource access
* resource access methods will not accept it. * methods will not accept it.
* <p>The thread context class loader will be used for * <p>The thread context class loader will be used for
* loading the resource. * loading the resource.
* @param path the absolute path within the class path * @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. * Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
* A leading slash will be removed, as the ClassLoader * A leading slash will be removed, as the ClassLoader resource access
* resource access methods will not accept it. * methods will not accept it.
* @param path the absolute path within the classpath * @param path the absolute path within the classpath
* @param classLoader the class loader to load the resource with, * @param classLoader the class loader to load the resource with,
* or {@code null} for the thread context class loader * 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. * Create a new {@code ClassPathResource} for {@code Class} usage.
* The path can be relative to the given class, * The path can be relative to the given class, or absolute within
* or absolute within the classpath via a leading slash. * the classpath via a leading slash.
* @param path relative or absolute path within the class path * @param path relative or absolute path within the class path
* @param clazz the class to load resources with * @param clazz the class to load resources with
* @see java.lang.Class#getResourceAsStream * @see java.lang.Class#getResourceAsStream
@@ -97,8 +97,8 @@ public class ClassPathResource extends AbstractFileResolvingResource {
} }
/** /**
* Create a new ClassPathResource with optional ClassLoader and Class. * Create a new {@code ClassPathResource} with optional {@code ClassLoader}
* Only for internal usage. * and {@code Class}. Only for internal usage.
* @param path relative or absolute path within the classpath * @param path relative or absolute path within the classpath
* @param classLoader the class loader to load the resource with, if any * @param classLoader the class loader to load the resource with, if any
* @param clazz the class to load resources 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; this.clazz = clazz;
} }
/** /**
* Return the path for this resource (as resource path within the class path). * 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. * Return the ClassLoader that this resource will be obtained from.
*/ */
public final ClassLoader getClassLoader() { 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. * This implementation checks for the resolution of a resource URL.
* @see java.lang.ClassLoader#getResource(String) * @see java.lang.ClassLoader#getResource(String)
@@ -130,14 +132,23 @@ public class ClassPathResource extends AbstractFileResolvingResource {
*/ */
@Override @Override
public boolean exists() { 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) { 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 { 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) { if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path); is = this.clazz.getResourceAsStream(this.path);
} }
else { else if (this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path); is = this.classLoader.getResourceAsStream(this.path);
} }
else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if (is == null) { if (is == null) {
throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist"); 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.ClassLoader#getResource(String)
* @see java.lang.Class#getResource(String) * @see java.lang.Class#getResource(String)
*/ */
@Override @Override
public URL getURL() throws IOException { public URL getURL() throws IOException {
URL url; URL url = resolveURL();
if (this.clazz != null) {
url = this.clazz.getResource(this.path);
}
else {
url = this.classLoader.getResource(this.path);
}
if (url == null) { if (url == null) {
throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist"); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 * <p>Clients which need to access the ClassLoader directly can do so
* in a uniform manner with the ResourceLoader, rather than relying * in a uniform manner with the ResourceLoader, rather than relying
* on the thread context ClassLoader. * 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(); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.core.io.VfsResource;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.PathMatcher; import org.springframework.util.PathMatcher;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.ResourceUtils; import org.springframework.util.ResourceUtils;
@@ -72,7 +73,7 @@ import org.springframework.util.StringUtils;
* <p><b>Ant-style Patterns:</b> * <p><b>Ant-style Patterns:</b>
* *
* <p>When the path location contains an Ant-style pattern, e.g.: * <p>When the path location contains an Ant-style pattern, e.g.:
* <pre> * <pre class="code">
* /WEB-INF/*-context.xml * /WEB-INF/*-context.xml
* com/mycompany/**&#47;applicationContext.xml * com/mycompany/**&#47;applicationContext.xml
* file:C:/some/path/*-context.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 * <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 * 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 * 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 * 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 * returned by {@code getResource("com/mycompany");}. If this base package
* node exists in multiple classloader locations, the actual end resource may * node exists in multiple classloader locations, the actual end resource may
* not be underneath. Therefore, preferably, use "{@code classpath*:}" with the same * not be underneath. Therefore, preferably, use "{@code classpath*:}" with the same
@@ -171,10 +176,10 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
private static Method equinoxResolveMethod; private static Method equinoxResolveMethod;
static { static {
// Detect Equinox OSGi (e.g. on WebSphere 6.1)
try { try {
Class<?> fileLocatorClass = PathMatchingResourcePatternResolver.class.getClassLoader().loadClass( // Detect Equinox OSGi (e.g. on WebSphere 6.1)
"org.eclipse.core.runtime.FileLocator"); Class<?> fileLocatorClass = ClassUtils.forName("org.eclipse.core.runtime.FileLocator",
PathMatchingResourcePatternResolver.class.getClassLoader());
equinoxResolveMethod = fileLocatorClass.getMethod("resolve", URL.class); equinoxResolveMethod = fileLocatorClass.getMethod("resolve", URL.class);
logger.debug("Found Equinox FileLocator for OSGi bundle URL resolution"); logger.debug("Found Equinox FileLocator for OSGi bundle URL resolution");
} }
@@ -198,17 +203,6 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
this.resourceLoader = new DefaultResourceLoader(); 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. * Create a new PathMatchingResourcePatternResolver.
* <p>ClassLoader access will happen via the thread context class loader. * <p>ClassLoader access will happen via the thread context class loader.
@@ -220,6 +214,18 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
this.resourceLoader = resourceLoader; 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. * Return the ResourceLoader that this pattern resolver works with.
*/ */
@@ -227,10 +233,6 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
return this.resourceLoader; return this.resourceLoader;
} }
/**
* Return the ClassLoader that this pattern resolver works with
* (never {@code null}).
*/
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
return getResourceLoader().getClassLoader(); return getResourceLoader().getClassLoader();
} }
@@ -298,7 +300,8 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
if (path.startsWith("/")) { if (path.startsWith("/")) {
path = path.substring(1); 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); Set<Resource> result = new LinkedHashSet<Resource>(16);
while (resourceUrls.hasMoreElements()) { while (resourceUrls.hasMoreElements()) {
URL url = resourceUrls.nextElement(); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public static Properties loadAllProperties(String resourceName, ClassLoader classLoader) throws IOException {
Assert.notNull(resourceName, "Resource name must not be null"); Assert.notNull(resourceName, "Resource name must not be null");
ClassLoader clToUse = classLoader; ClassLoader classLoaderToUse = classLoader;
if (clToUse == null) { if (classLoaderToUse == null) {
clToUse = ClassUtils.getDefaultClassLoader(); classLoaderToUse = ClassUtils.getDefaultClassLoader();
} }
Enumeration<URL> urls = (classLoaderToUse != null ? classLoaderToUse.getResources(resourceName) :
ClassLoader.getSystemResources(resourceName));
Properties props = new Properties(); Properties props = new Properties();
Enumeration urls = clToUse.getResources(resourceName);
while (urls.hasMoreElements()) { while (urls.hasMoreElements()) {
URL url = (URL) urls.nextElement(); URL url = urls.nextElement();
URLConnection con = url.openConnection(); URLConnection con = url.openConnection();
ResourceUtils.useCachesIfNecessary(con); ResourceUtils.useCachesIfNecessary(con);
InputStream is = con.getInputStream(); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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) { public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
Assert.notNull(factoryClass, "'factoryClass' must not be null"); Assert.notNull(factoryClass, "'factoryClass' must not be null");
if (classLoader == null) { ClassLoader classLoaderToUse = classLoader;
classLoader = SpringFactoriesLoader.class.getClassLoader(); if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
} }
List<String> factoryNames = loadFactoryNames(factoryClass, classLoader); List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames); logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
} }
List<T> result = new ArrayList<T>(factoryNames.size()); List<T> result = new ArrayList<T>(factoryNames.size());
for (String factoryName : factoryNames) { for (String factoryName : factoryNames) {
result.add(instantiateFactory(factoryName, factoryClass, classLoader)); result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
} }
OrderComparator.sort(result); OrderComparator.sort(result);
return result; return result;
@@ -85,8 +86,9 @@ public abstract class SpringFactoriesLoader {
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName(); String factoryClassName = factoryClass.getName();
try { try {
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List<String> result = new ArrayList<String>(); List<String> result = new ArrayList<String>();
Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
while (urls.hasMoreElements()) { while (urls.hasMoreElements()) {
URL url = urls.nextElement(); URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
package org.springframework.core.type.filter; package org.springframework.core.type.filter;
import org.springframework.util.ClassUtils;
/** /**
* A simple filter which matches classes that are assignable to a given type. * 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 { public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter {
private final Class targetType; private final Class<?> targetType;
/** /**
* Create a new AssignableTypeFilter for the given type. * Create a new AssignableTypeFilter for the given type.
* @param targetType the type to match * @param targetType the type to match
*/ */
public AssignableTypeFilter(Class targetType) { public AssignableTypeFilter(Class<?> targetType) {
super(true, true); super(true, true);
this.targetType = targetType; this.targetType = targetType;
} }
@@ -59,15 +61,15 @@ public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter
return true; return true;
} }
else if (Object.class.getName().equals(typeName)) { else if (Object.class.getName().equals(typeName)) {
return Boolean.FALSE; return false;
} }
else if (typeName.startsWith("java.")) { else if (typeName.startsWith("java")) {
try { try {
Class clazz = getClass().getClassLoader().loadClass(typeName); Class<?> clazz = ClassUtils.forName(typeName, getClass().getClassLoader());
return Boolean.valueOf(this.targetType.isAssignableFrom(clazz)); return this.targetType.isAssignableFrom(clazz);
} }
catch (ClassNotFoundException ex) { catch (Throwable ex) {
// Class not found - can't determine a match that way. // Class not regularly loadable - can't determine a match that way.
} }
} }
return null; return null;

View File

@@ -142,12 +142,14 @@ public abstract class ClassUtils {
* ClassLoader, if available; the ClassLoader that loaded the ClassUtils * ClassLoader, if available; the ClassLoader that loaded the ClassUtils
* class will be used as fallback. * class will be used as fallback.
* <p>Call this method if you intend to use the thread context ClassLoader * <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 * for example, for class path resource loading (but not necessarily for
* {@code Class.forName}, which accepts a {@code null} ClassLoader * {@code Class.forName}, which accepts a {@code null} ClassLoader
* reference as well). * 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 Thread#getContextClassLoader()
* @see ClassLoader#getSystemClassLoader()
*/ */
public static ClassLoader getDefaultClassLoader() { public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null; ClassLoader cl = null;
@@ -155,11 +157,20 @@ public abstract class ClassUtils {
cl = Thread.currentThread().getContextClassLoader(); cl = Thread.currentThread().getContextClassLoader();
} }
catch (Throwable ex) { catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back to system class loader... // Cannot access thread context ClassLoader - falling back...
} }
if (cl == null) { if (cl == null) {
// No thread context class loader -> use class loader of this class. // No thread context class loader -> use class loader of this class.
cl = ClassUtils.class.getClassLoader(); 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; return cl;
} }
@@ -247,19 +258,19 @@ public abstract class ClassUtils {
return Array.newInstance(elementClass, 0).getClass(); return Array.newInstance(elementClass, 0).getClass();
} }
ClassLoader classLoaderToUse = classLoader; ClassLoader clToUse = classLoader;
if (classLoaderToUse == null) { if (clToUse == null) {
classLoaderToUse = getDefaultClassLoader(); clToUse = getDefaultClassLoader();
} }
try { try {
return classLoaderToUse.loadClass(name); return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name));
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
int lastDotIndex = name.lastIndexOf('.'); int lastDotIndex = name.lastIndexOf('.');
if (lastDotIndex != -1) { if (lastDotIndex != -1) {
String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1); String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1);
try { try {
return classLoaderToUse.loadClass(innerClassName); return (clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName));
} }
catch (ClassNotFoundException ex2) { catch (ClassNotFoundException ex2) {
// swallow - let original exception get through // 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"); Assert.notNull(resourceLocation, "Resource location must not be null");
if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) { if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) {
String path = resourceLocation.substring(CLASSPATH_URL_PREFIX.length()); 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) { if (url == null) {
String description = "class path resource [" + path + "]"; String description = "class path resource [" + path + "]";
throw new FileNotFoundException( throw new FileNotFoundException(
@@ -159,7 +160,8 @@ public abstract class ResourceUtils {
if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) { if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) {
String path = resourceLocation.substring(CLASSPATH_URL_PREFIX.length()); String path = resourceLocation.substring(CLASSPATH_URL_PREFIX.length());
String description = "class path resource [" + path + "]"; 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) { if (url == null) {
throw new FileNotFoundException( throw new FileNotFoundException(
description + " cannot be resolved to absolute file path " + 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public Class<?> findType(String typeName) throws EvaluationException {
String nameToLookup = typeName; String nameToLookup = typeName;
try { try {
return this.classLoader.loadClass(nameToLookup); return ClassUtils.forName(nameToLookup, this.classLoader);
} }
catch (ClassNotFoundException ey) { catch (ClassNotFoundException ey) {
// try any registered prefixes before giving up // try any registered prefixes before giving up
@@ -105,7 +105,7 @@ public class StandardTypeLocator implements TypeLocator {
for (String prefix : this.knownPackagePrefixes) { for (String prefix : this.knownPackagePrefixes) {
try { try {
nameToLookup = prefix + "." + typeName; nameToLookup = prefix + "." + typeName;
return this.classLoader.loadClass(nameToLookup); return ClassUtils.forName(nameToLookup, this.classLoader);
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
// might be a different prefix // 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; boolean isOracleCon;
try { try {
Class<?> oracleConClass = getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection"); Class<?> oracleConClass = con.getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection");
isOracleCon = oracleConClass.isInstance(con); isOracleCon = oracleConClass.isInstance(con);
} }
catch (ClassNotFoundException ex) { 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.BeanNameAware;
import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@@ -73,8 +74,8 @@ public class FilterDefinitionFactoryBean implements FactoryBean<FilterDefinition
static { static {
// Hibernate 3.6 TypeResolver class available? // Hibernate 3.6 TypeResolver class available?
try { try {
Class<?> trClass = FilterDefinitionFactoryBean.class.getClassLoader().loadClass( Class<?> trClass = ClassUtils.forName("org.hibernate.type.TypeResolver",
"org.hibernate.type.TypeResolver"); FilterDefinitionFactoryBean.class.getClassLoader());
heuristicTypeMethod = trClass.getMethod("heuristicType", String.class); heuristicTypeMethod = trClass.getMethod("heuristicType", String.class);
typeResolver = trClass.newInstance(); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
/** /**
@@ -154,8 +155,7 @@ public class TestContextManager {
* registered for this {@code TestContextManager} in reverse order. * registered for this {@code TestContextManager} in reverse order.
*/ */
private List<TestExecutionListener> getReversedTestExecutionListeners() { private List<TestExecutionListener> getReversedTestExecutionListeners() {
List<TestExecutionListener> listenersReversed = new ArrayList<TestExecutionListener>( List<TestExecutionListener> listenersReversed = new ArrayList<TestExecutionListener>(getTestExecutionListeners());
getTestExecutionListeners());
Collections.reverse(listenersReversed); Collections.reverse(listenersReversed);
return listenersReversed; return listenersReversed;
} }
@@ -188,18 +188,17 @@ public class TestContextManager {
while (declaringClass != null) { while (declaringClass != null) {
TestExecutionListeners testExecutionListeners = declaringClass.getAnnotation(annotationType); TestExecutionListeners testExecutionListeners = declaringClass.getAnnotation(annotationType);
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("Retrieved @TestExecutionListeners [" + testExecutionListeners logger.trace("Retrieved @TestExecutionListeners [" + testExecutionListeners +
+ "] for declaring class [" + declaringClass + "]."); "] for declaring class [" + declaringClass + "].");
} }
Class<? extends TestExecutionListener>[] valueListenerClasses = testExecutionListeners.value(); Class<? extends TestExecutionListener>[] valueListenerClasses = testExecutionListeners.value();
Class<? extends TestExecutionListener>[] listenerClasses = testExecutionListeners.listeners(); Class<? extends TestExecutionListener>[] listenerClasses = testExecutionListeners.listeners();
if (!ObjectUtils.isEmpty(valueListenerClasses) && !ObjectUtils.isEmpty(listenerClasses)) { if (!ObjectUtils.isEmpty(valueListenerClasses) && !ObjectUtils.isEmpty(listenerClasses)) {
String msg = String.format( String msg = String.format("Test class [%s] has been configured with @TestExecutionListeners' " +
"Test class [%s] has been configured with @TestExecutionListeners' 'value' [%s] " "'value' [%s] and 'listeners' [%s] attributes. Use one or the other, but not both.",
+ "and 'listeners' [%s] attributes. Use one or the other, but not both.", declaringClass, ObjectUtils.nullSafeToString(valueListenerClasses),
declaringClass, ObjectUtils.nullSafeToString(valueListenerClasses), ObjectUtils.nullSafeToString(listenerClasses));
ObjectUtils.nullSafeToString(listenerClasses));
logger.error(msg); logger.error(msg);
throw new IllegalStateException(msg); throw new IllegalStateException(msg);
} else if (!ObjectUtils.isEmpty(valueListenerClasses)) { } else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
@@ -221,9 +220,9 @@ public class TestContextManager {
} }
catch (NoClassDefFoundError err) { catch (NoClassDefFoundError err) {
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
logger.info(String.format("Could not instantiate TestExecutionListener class [%s]. " logger.info(String.format("Could not instantiate TestExecutionListener class [%s]. " +
+ "Specify custom listener classes or make the default listener classes " "Specify custom listener classes or make the default listener classes " +
+ "(and their dependencies) available.", listenerClass.getName())); "(and their dependencies) available.", listenerClass.getName()));
} }
} }
} }
@@ -236,14 +235,15 @@ public class TestContextManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected Set<Class<? extends TestExecutionListener>> getDefaultTestExecutionListenerClasses() { protected Set<Class<? extends TestExecutionListener>> getDefaultTestExecutionListenerClasses() {
Set<Class<? extends TestExecutionListener>> defaultListenerClasses = new LinkedHashSet<Class<? extends TestExecutionListener>>(); Set<Class<? extends TestExecutionListener>> defaultListenerClasses = new LinkedHashSet<Class<? extends TestExecutionListener>>();
ClassLoader cl = getClass().getClassLoader();
for (String className : DEFAULT_TEST_EXECUTION_LISTENER_CLASS_NAMES) { for (String className : DEFAULT_TEST_EXECUTION_LISTENER_CLASS_NAMES) {
try { try {
defaultListenerClasses.add((Class<? extends TestExecutionListener>) getClass().getClassLoader().loadClass( defaultListenerClasses.add((Class<? extends TestExecutionListener>) ClassUtils.forName(className, cl));
className)); }
} catch (Throwable t) { catch (Throwable ex) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Could not load default TestExecutionListener class [" + className logger.debug("Could not load default TestExecutionListener class [" + className +
+ "]. Specify custom listener classes or make the default listener classes available.", t); "]. Specify custom listener classes or make the default listener classes available.", ex);
} }
} }
} }
@@ -273,9 +273,10 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) { for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
try { try {
testExecutionListener.beforeTestClass(getTestContext()); testExecutionListener.beforeTestClass(getTestContext());
} catch (Exception ex) { }
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener catch (Exception ex) {
+ "] 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; throw ex;
} }
} }
@@ -305,9 +306,10 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) { for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
try { try {
testExecutionListener.prepareTestInstance(getTestContext()); testExecutionListener.prepareTestInstance(getTestContext());
} catch (Exception ex) { }
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener catch (Exception ex) {
+ "] to prepare test instance [" + testInstance + "]", ex); logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
"] to prepare test instance [" + testInstance + "]", ex);
throw ex; throw ex;
} }
} }
@@ -341,10 +343,11 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) { for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
try { try {
testExecutionListener.beforeTestMethod(getTestContext()); testExecutionListener.beforeTestMethod(getTestContext());
} catch (Exception ex) { }
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener catch (Exception ex) {
+ "] to process 'before' execution of test method [" + testMethod + "] for test instance [" logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
+ testInstance + "]", ex); "] to process 'before' execution of test method [" + testMethod + "] for test instance [" +
testInstance + "]", ex);
throw ex; throw ex;
} }
} }
@@ -388,10 +391,11 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) { for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
try { try {
testExecutionListener.afterTestMethod(getTestContext()); testExecutionListener.afterTestMethod(getTestContext());
} catch (Exception ex) { }
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener catch (Exception ex) {
+ "] to process 'after' execution for test: method [" + testMethod + "], instance [" logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
+ testInstance + "], exception [" + exception + "]", ex); "] to process 'after' execution for test: method [" + testMethod + "], instance [" +
testInstance + "], exception [" + exception + "]", ex);
if (afterTestMethodException == null) { if (afterTestMethodException == null) {
afterTestMethodException = ex; afterTestMethodException = ex;
} }
@@ -429,9 +433,10 @@ public class TestContextManager {
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) { for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
try { try {
testExecutionListener.afterTestClass(getTestContext()); testExecutionListener.afterTestClass(getTestContext());
} catch (Exception ex) { }
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener catch (Exception ex) {
+ "] 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) { if (afterTestClassException == null) {
afterTestClassException = ex; 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@@ -154,9 +155,9 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
private static Class<?> transactionSynchronizationRegistryClass; private static Class<?> transactionSynchronizationRegistryClass;
static { static {
ClassLoader cl = JtaTransactionManager.class.getClassLoader();
try { try {
transactionSynchronizationRegistryClass = cl.loadClass(TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME); transactionSynchronizationRegistryClass = ClassUtils.forName(
TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME, JtaTransactionManager.class.getClassLoader());
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
// JTA 1.1 API not available... simply proceed the JTA 1.0 way. // JTA 1.1 API not available... simply proceed the JTA 1.0 way.