Consistent use of @Nullable across the codebase (even for internals)

Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments.

Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit.

Issue: SPR-15540
This commit is contained in:
Juergen Hoeller
2017-06-07 14:17:48 +02:00
parent ffc3f6d87d
commit f813712f5b
1493 changed files with 10670 additions and 9172 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -83,7 +83,7 @@ public class CaffeineCache extends AbstractValueAdaptingCache {
}
@Override
public ValueWrapper get(@Nullable Object key) {
public ValueWrapper get(Object key) {
if (this.cache instanceof LoadingCache) {
Object value = ((LoadingCache<Object, Object>) this.cache).get(key);
return toValueWrapper(value);
@@ -94,7 +94,7 @@ public class CaffeineCache extends AbstractValueAdaptingCache {
@SuppressWarnings("unchecked")
@Override
@Nullable
public <T> T get(@Nullable Object key, final Callable<T> valueLoader) {
public <T> T get(Object key, final Callable<T> valueLoader) {
return (T) fromStoreValue(this.cache.get(key, new LoadFunction(valueLoader)));
}
@@ -104,20 +104,20 @@ public class CaffeineCache extends AbstractValueAdaptingCache {
}
@Override
public void put(@Nullable Object key, @Nullable Object value) {
public void put(Object key, @Nullable Object value) {
this.cache.put(key, toStoreValue(value));
}
@Override
@Nullable
public ValueWrapper putIfAbsent(@Nullable Object key, @Nullable final Object value) {
public ValueWrapper putIfAbsent(Object key, @Nullable final Object value) {
PutIfAbsentFunction callable = new PutIfAbsentFunction(value);
Object result = this.cache.get(key, callable);
return (callable.called ? null : toValueWrapper(result));
}
@Override
public void evict(@Nullable Object key) {
public void evict(Object key) {
this.cache.invalidate(key);
}
@@ -133,7 +133,7 @@ public class CaffeineCache extends AbstractValueAdaptingCache {
private boolean called;
public PutIfAbsentFunction(Object value) {
public PutIfAbsentFunction(@Nullable Object value) {
this.value = value;
}

View File

@@ -64,7 +64,7 @@ public class EhCacheCache implements Cache {
}
@Override
public ValueWrapper get(@Nullable Object key) {
public ValueWrapper get(Object key) {
Element element = lookup(key);
return toValueWrapper(element);
}
@@ -72,7 +72,7 @@ public class EhCacheCache implements Cache {
@SuppressWarnings("unchecked")
@Override
@Nullable
public <T> T get(@Nullable Object key, Callable<T> valueLoader) {
public <T> T get(Object key, Callable<T> valueLoader) {
Element element = lookup(key);
if (element != null) {
return (T) element.getObjectValue();
@@ -110,7 +110,7 @@ public class EhCacheCache implements Cache {
@Override
@SuppressWarnings("unchecked")
@Nullable
public <T> T get(@Nullable Object key, Class<T> type) {
public <T> T get(Object key, @Nullable Class<T> type) {
Element element = this.cache.get(key);
Object value = (element != null ? element.getObjectValue() : null);
if (value != null && type != null && !type.isInstance(value)) {
@@ -120,18 +120,18 @@ public class EhCacheCache implements Cache {
}
@Override
public void put(@Nullable Object key, @Nullable Object value) {
public void put(Object key, @Nullable Object value) {
this.cache.put(new Element(key, value));
}
@Override
public ValueWrapper putIfAbsent(@Nullable Object key, @Nullable Object value) {
public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
Element existingElement = this.cache.putIfAbsent(new Element(key, value));
return toValueWrapper(existingElement);
}
@Override
public void evict(@Nullable Object key) {
public void evict(Object key) {
this.cache.remove(key);
}
@@ -141,11 +141,13 @@ public class EhCacheCache implements Cache {
}
@Nullable
private Element lookup(Object key) {
return this.cache.get(key);
}
private ValueWrapper toValueWrapper(Element element) {
@Nullable
private ValueWrapper toValueWrapper(@Nullable Element element) {
return (element != null ? new SimpleValueWrapper(element.getObjectValue()) : null);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -24,6 +24,8 @@ import net.sf.ehcache.Status;
import org.springframework.cache.Cache;
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* CacheManager backed by an EhCache {@link net.sf.ehcache.CacheManager}.
@@ -64,6 +66,7 @@ public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManag
/**
* Return the backing EhCache {@link net.sf.ehcache.CacheManager}.
*/
@Nullable
public net.sf.ehcache.CacheManager getCacheManager() {
return this.cacheManager;
}
@@ -79,7 +82,10 @@ public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManag
@Override
protected Collection<Cache> loadCaches() {
Status status = getCacheManager().getStatus();
net.sf.ehcache.CacheManager cacheManager = getCacheManager();
Assert.state(cacheManager != null, "No CacheManager set");
Status status = cacheManager.getStatus();
if (!Status.STATUS_ALIVE.equals(status)) {
throw new IllegalStateException(
"An 'alive' EhCache CacheManager is required - current cache is " + status.toString());
@@ -95,8 +101,11 @@ public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManag
@Override
protected Cache getMissingCache(String name) {
net.sf.ehcache.CacheManager cacheManager = getCacheManager();
Assert.state(cacheManager != null, "No CacheManager set");
// Check the EhCache cache again (in case the cache was added at runtime)
Ehcache ehcache = getCacheManager().getEhcache(name);
Ehcache ehcache = cacheManager.getEhcache(name);
if (ehcache != null) {
return new EhCacheCache(ehcache);
}

View File

@@ -76,7 +76,7 @@ public class JCacheCache extends AbstractValueAdaptingCache {
}
@Override
public <T> T get(@Nullable Object key, Callable<T> valueLoader) {
public <T> T get(Object key, Callable<T> valueLoader) {
try {
return this.cache.invoke(key, new ValueLoaderEntryProcessor<T>(), valueLoader);
}
@@ -86,18 +86,18 @@ public class JCacheCache extends AbstractValueAdaptingCache {
}
@Override
public void put(@Nullable Object key, @Nullable Object value) {
public void put(Object key, @Nullable Object value) {
this.cache.put(key, toStoreValue(value));
}
@Override
public ValueWrapper putIfAbsent(@Nullable Object key, @Nullable Object value) {
public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
boolean set = this.cache.putIfAbsent(key, toStoreValue(value));
return (set ? null : get(key));
}
@Override
public void evict(@Nullable Object key) {
public void evict(Object key) {
this.cache.remove(key);
}
@@ -111,8 +111,8 @@ public class JCacheCache extends AbstractValueAdaptingCache {
@SuppressWarnings("unchecked")
@Override
public T process(MutableEntry<Object, Object> entry, Object... arguments)
throws EntryProcessorException {
@Nullable
public T process(MutableEntry<Object, Object> entry, Object... arguments) throws EntryProcessorException {
Callable<T> valueLoader = (Callable<T>) arguments[0];
if (entry.exists()) {
return (T) fromStoreValue(entry.getValue());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -23,6 +23,8 @@ import javax.cache.Caching;
import org.springframework.cache.Cache;
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* {@link org.springframework.cache.CacheManager} implementation
@@ -67,6 +69,7 @@ public class JCacheCacheManager extends AbstractTransactionSupportingCacheManage
/**
* Return the backing JCache {@link javax.cache.CacheManager}.
*/
@Nullable
public javax.cache.CacheManager getCacheManager() {
return this.cacheManager;
}
@@ -100,9 +103,12 @@ public class JCacheCacheManager extends AbstractTransactionSupportingCacheManage
@Override
protected Collection<Cache> loadCaches() {
CacheManager cacheManager = getCacheManager();
Assert.state(cacheManager != null, "No CacheManager set");
Collection<Cache> caches = new LinkedHashSet<>();
for (String cacheName : getCacheManager().getCacheNames()) {
javax.cache.Cache<Object, Object> jcache = getCacheManager().getCache(cacheName);
for (String cacheName : cacheManager.getCacheNames()) {
javax.cache.Cache<Object, Object> jcache = cacheManager.getCache(cacheName);
caches.add(new JCacheCache(jcache, isAllowNullValues()));
}
return caches;
@@ -110,8 +116,11 @@ public class JCacheCacheManager extends AbstractTransactionSupportingCacheManage
@Override
protected Cache getMissingCache(String name) {
CacheManager cacheManager = getCacheManager();
Assert.state(cacheManager != null, "No CacheManager set");
// Check the JCache cache again (in case the cache was added at runtime)
javax.cache.Cache<Object, Object> jcache = getCacheManager().getCache(name);
javax.cache.Cache<Object, Object> jcache = cacheManager.getCache(name);
if (jcache != null) {
return new JCacheCache(jcache, isAllowNullValues());
}

View File

@@ -69,7 +69,7 @@ public class JCacheManagerFactoryBean
}
@Override
public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -41,7 +41,7 @@ public class AbstractJCacheConfiguration extends AbstractCachingConfiguration {
protected CacheResolver exceptionCacheResolver;
@Override
protected void useCachingConfigurer(@Nullable CachingConfigurer config) {
protected void useCachingConfigurer(CachingConfigurer config) {
super.useCachingConfigurer(config);
if (config instanceof JCacheConfigurer) {
this.exceptionCacheResolver = ((JCacheConfigurer) config).exceptionCacheResolver();

View File

@@ -80,7 +80,6 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
public void afterPropertiesSet() {
Assert.state(getCacheOperationSource() != null, "The 'cacheOperationSource' property is required: " +
"If there are no cacheable methods, then don't use a cache aspect.");
Assert.state(getErrorHandler() != null, "The 'errorHandler' property is required");
this.cacheResultInterceptor = new CacheResultInterceptor(getErrorHandler());
this.cachePutInterceptor = new CachePutInterceptor(getErrorHandler());
@@ -94,7 +93,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
// Check whether aspect is enabled to cope with cases where the AJ is pulled in automatically
if (this.initialized) {
Class<?> targetClass = getTargetClass(target);
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
JCacheOperation<?> operation = getCacheOperationSource().getCacheOperation(method, targetClass);
if (operation != null) {
CacheOperationInvocationContext<?> context =
@@ -114,14 +113,6 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
(JCacheOperation<Annotation>) operation, target, args);
}
private Class<?> getTargetClass(Object target) {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
if (targetClass == null && target != null) {
targetClass = target.getClass();
}
return targetClass;
}
@SuppressWarnings("unchecked")
private Object execute(CacheOperationInvocationContext<?> context, CacheOperationInvoker invoker) {
CacheOperationInvoker adapter = new CacheOperationInvokerAdapter(invoker);

View File

@@ -72,22 +72,22 @@ public class TransactionAwareCacheDecorator implements Cache {
}
@Override
public ValueWrapper get(@Nullable Object key) {
public ValueWrapper get(Object key) {
return this.targetCache.get(key);
}
@Override
public <T> T get(@Nullable Object key, Class<T> type) {
public <T> T get(Object key, @Nullable Class<T> type) {
return this.targetCache.get(key, type);
}
@Override
public <T> T get(@Nullable Object key, Callable<T> valueLoader) {
public <T> T get(Object key, Callable<T> valueLoader) {
return this.targetCache.get(key, valueLoader);
}
@Override
public void put(@Nullable final Object key, @Nullable final Object value) {
public void put(final Object key, @Nullable final Object value) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
@@ -102,12 +102,12 @@ public class TransactionAwareCacheDecorator implements Cache {
}
@Override
public ValueWrapper putIfAbsent(@Nullable final Object key, @Nullable final Object value) {
public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
return this.targetCache.putIfAbsent(key, value);
}
@Override
public void evict(@Nullable final Object key) {
public void evict(final Object key) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 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.
@@ -75,7 +75,8 @@ public class TransactionAwareCacheManagerProxy implements CacheManager, Initiali
@Override
public Cache getCache(String name) {
return new TransactionAwareCacheDecorator(this.targetCacheManager.getCache(name));
Cache targetCache = this.targetCacheManager.getCache(name);
return (targetCache != null ? new TransactionAwareCacheDecorator(targetCache) : null);
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -17,6 +17,7 @@
package org.springframework.mail;
import org.springframework.core.NestedRuntimeException;
import org.springframework.lang.Nullable;
/**
* Base class for all mail exceptions.
@@ -39,7 +40,7 @@ public abstract class MailException extends NestedRuntimeException {
* @param msg the detail message
* @param cause the root cause from the mail API in use
*/
public MailException(String msg, Throwable cause) {
public MailException(@Nullable String msg, @Nullable Throwable cause) {
super(msg, cause);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2005 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,26 +35,26 @@ import java.util.Date;
*/
public interface MailMessage {
public void setFrom(String from) throws MailParseException;
void setFrom(String from) throws MailParseException;
public void setReplyTo(String replyTo) throws MailParseException;
void setReplyTo(String replyTo) throws MailParseException;
public void setTo(String to) throws MailParseException;
void setTo(String to) throws MailParseException;
public void setTo(String[] to) throws MailParseException;
void setTo(String[] to) throws MailParseException;
public void setCc(String cc) throws MailParseException;
void setCc(String cc) throws MailParseException;
public void setCc(String[] cc) throws MailParseException;
void setCc(String[] cc) throws MailParseException;
public void setBcc(String bcc) throws MailParseException;
void setBcc(String bcc) throws MailParseException;
public void setBcc(String[] bcc) throws MailParseException;
void setBcc(String[] bcc) throws MailParseException;
public void setSentDate(Date sentDate) throws MailParseException;
void setSentDate(Date sentDate) throws MailParseException;
public void setSubject(String subject) throws MailParseException;
void setSubject(String subject) throws MailParseException;
public void setText(String text) throws MailParseException;
void setText(String text) throws MailParseException;
}

View File

@@ -21,6 +21,7 @@ import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
@@ -51,7 +52,7 @@ public class MailSendException extends MailException {
* @param msg the detail message
* @param cause the root cause from the mail API in use
*/
public MailSendException(String msg, Throwable cause) {
public MailSendException(String msg, @Nullable Throwable cause) {
super(msg, cause);
this.failedMessages = new LinkedHashMap<>();
}
@@ -66,7 +67,7 @@ public class MailSendException extends MailException {
* @param failedMessages Map of failed messages as keys and thrown
* exceptions as values
*/
public MailSendException(String msg, Throwable cause, Map<Object, Exception> failedMessages) {
public MailSendException(@Nullable String msg, @Nullable Throwable cause, Map<Object, Exception> failedMessages) {
super(msg, cause);
this.failedMessages = new LinkedHashMap<>(failedMessages);
this.messageExceptions = failedMessages.values().toArray(new Exception[failedMessages.size()]);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -19,6 +19,7 @@ package org.springframework.mail;
import java.io.Serializable;
import java.util.Date;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -68,10 +69,9 @@ public class SimpleMailMessage implements MailMessage, Serializable {
/**
* Copy constructor for creating a new {@code SimpleMailMessage} from the state
* of an existing {@code SimpleMailMessage} instance.
* @throws IllegalArgumentException if the supplied message is {@code null}
*/
public SimpleMailMessage(SimpleMailMessage original) {
Assert.notNull(original, "The 'original' message argument cannot be null");
Assert.notNull(original, "'original' message argument must not be null");
this.from = original.getFrom();
this.replyTo = original.getReplyTo();
if (original.getTo() != null) {
@@ -94,6 +94,7 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.from = from;
}
@Nullable
public String getFrom() {
return this.from;
}
@@ -103,8 +104,9 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.replyTo = replyTo;
}
@Nullable
public String getReplyTo() {
return replyTo;
return this.replyTo;
}
@Override
@@ -117,6 +119,7 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.to = to;
}
@Nullable
public String[] getTo() {
return this.to;
}
@@ -131,8 +134,9 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.cc = cc;
}
@Nullable
public String[] getCc() {
return cc;
return this.cc;
}
@Override
@@ -145,8 +149,9 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.bcc = bcc;
}
@Nullable
public String[] getBcc() {
return bcc;
return this.bcc;
}
@Override
@@ -154,8 +159,9 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.sentDate = sentDate;
}
@Nullable
public Date getSentDate() {
return sentDate;
return this.sentDate;
}
@Override
@@ -163,6 +169,7 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.subject = subject;
}
@Nullable
public String getSubject() {
return this.subject;
}
@@ -172,6 +179,7 @@ public class SimpleMailMessage implements MailMessage, Serializable {
this.text = text;
}
@Nullable
public String getText() {
return this.text;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -166,6 +166,7 @@ public class JavaMailSenderImpl implements JavaMailSender {
/**
* Return the mail protocol.
*/
@Nullable
public String getProtocol() {
return this.protocol;
}
@@ -181,6 +182,7 @@ public class JavaMailSenderImpl implements JavaMailSender {
/**
* Return the mail server host.
*/
@Nullable
public String getHost() {
return this.host;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 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.
@@ -198,7 +198,7 @@ public class MimeMessageHelper {
* @param encoding the character encoding to use for the message
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, boolean)
*/
public MimeMessageHelper(MimeMessage mimeMessage, String encoding) {
public MimeMessageHelper(MimeMessage mimeMessage, @Nullable String encoding) {
this.mimeMessage = mimeMessage;
this.encoding = (encoding != null ? encoding : getDefaultEncoding(mimeMessage));
this.fileTypeMap = getDefaultFileTypeMap(mimeMessage);
@@ -242,7 +242,7 @@ public class MimeMessageHelper {
* @throws MessagingException if multipart creation failed
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int, String)
*/
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, String encoding)
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, @Nullable String encoding)
throws MessagingException {
this(mimeMessage, (multipart ? MULTIPART_MODE_MIXED_RELATED : MULTIPART_MODE_NO), encoding);
@@ -284,7 +284,7 @@ public class MimeMessageHelper {
* @see #MULTIPART_MODE_RELATED
* @see #MULTIPART_MODE_MIXED_RELATED
*/
public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode, String encoding)
public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode, @Nullable String encoding)
throws MessagingException {
this.mimeMessage = mimeMessage;
@@ -473,7 +473,7 @@ public class MimeMessageHelper {
* @see javax.activation.FileTypeMap#getDefaultFileTypeMap
* @see ConfigurableMimeFileTypeMap
*/
public void setFileTypeMap(FileTypeMap fileTypeMap) {
public void setFileTypeMap(@Nullable FileTypeMap fileTypeMap) {
this.fileTypeMap = (fileTypeMap != null ? fileTypeMap : getDefaultFileTypeMap(getMimeMessage()));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -24,6 +24,8 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.Lifecycle;
import org.springframework.jndi.JndiLocatorSupport;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager}
@@ -105,10 +107,26 @@ public abstract class TimerManagerAccessor extends JndiLocatorSupport
}
}
/**
* Return the configured TimerManager, if any.
* @return the TimerManager, or {@code null} if not available
*/
@Nullable
protected final TimerManager getTimerManager() {
return this.timerManager;
}
/**
* Obtain the TimerManager for actual use.
* @return the TimerManager (never {@code null})
* @throws IllegalStateException in case of no TimerManager set
* @since 5.0
*/
protected TimerManager obtainTimerManager() {
Assert.notNull(this.timerManager, "No TimerManager set");
return this.timerManager;
}
//---------------------------------------------------------------------
// Implementation of Lifecycle interface

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.Lifecycle;
import org.springframework.util.Assert;
/**
* {@link org.springframework.beans.factory.FactoryBean} that retrieves a
@@ -80,7 +81,7 @@ public class TimerManagerFactoryBean extends TimerManagerAccessor
public void afterPropertiesSet() throws NamingException {
super.afterPropertiesSet();
if (this.scheduledTimerListeners != null) {
TimerManager timerManager = getTimerManager();
TimerManager timerManager = obtainTimerManager();
for (ScheduledTimerListener scheduledTask : this.scheduledTimerListeners) {
Timer timer;
if (scheduledTask.isOneTimeTask()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -61,7 +61,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
@Override
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false));
Timer timer = getTimerManager().schedule(futureTask, startTime);
Timer timer = obtainTimerManager().schedule(futureTask, startTime);
futureTask.setTimer(timer);
return futureTask;
}
@@ -69,7 +69,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, startTime, period);
Timer timer = obtainTimerManager().scheduleAtFixedRate(futureTask, startTime, period);
futureTask.setTimer(timer);
return futureTask;
}
@@ -77,7 +77,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, 0, period);
Timer timer = obtainTimerManager().scheduleAtFixedRate(futureTask, 0, period);
futureTask.setTimer(timer);
return futureTask;
}
@@ -85,7 +85,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
Timer timer = getTimerManager().schedule(futureTask, startTime, delay);
Timer timer = obtainTimerManager().schedule(futureTask, startTime, delay);
futureTask.setTimer(timer);
return futureTask;
}
@@ -93,7 +93,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
Timer timer = getTimerManager().schedule(futureTask, 0, delay);
Timer timer = obtainTimerManager().schedule(futureTask, 0, delay);
futureTask.setTimer(timer);
return futureTask;
}
@@ -171,7 +171,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
if (this.scheduledExecutionTime == null) {
return null;
}
setTimer(getTimerManager().schedule(this, this.scheduledExecutionTime));
setTimer(obtainTimerManager().schedule(this, this.scheduledExecutionTime));
return this;
}

View File

@@ -147,7 +147,7 @@ public class LocalDataSourceJobStore extends JobStoreCMT {
// No, if HSQL is the platform, we really don't want to use locks...
try {
String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, "getDatabaseProductName").toString();
String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, "getDatabaseProductName");
productName = JdbcUtils.commonDatabaseName(productName);
if (productName != null && productName.toLowerCase().contains("hsql")) {
setUseDBLocks(false);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 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.
@@ -72,9 +72,6 @@ public class LocalTaskExecutorThreadPool implements ThreadPool {
@Override
public boolean runInThread(Runnable runnable) {
if (runnable == null) {
return false;
}
try {
this.taskExecutor.execute(runnable);
return true;

View File

@@ -142,7 +142,7 @@ public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethod
}
@Override
public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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,8 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Wrapper that adapts from the Quartz {@link ClassLoadHelper} interface
@@ -74,7 +76,7 @@ public class ResourceLoaderClassLoadHelper implements ClassLoadHelper {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return this.resourceLoader.getClassLoader().loadClass(name);
return ClassUtils.forName(name, this.resourceLoader.getClassLoader());
}
@SuppressWarnings("unchecked")
@@ -124,7 +126,9 @@ public class ResourceLoaderClassLoadHelper implements ClassLoadHelper {
@Override
public ClassLoader getClassLoader() {
return this.resourceLoader.getClassLoader();
ClassLoader classLoader = this.resourceLoader.getClassLoader();
Assert.state(classLoader != null, "No ClassLoader");
return classLoader;
}
}

View File

@@ -42,6 +42,7 @@ import org.springframework.context.SmartLifecycle;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.SchedulingException;
import org.springframework.util.CollectionUtils;
@@ -114,6 +115,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
* @see #setApplicationContext
* @see ResourceLoaderClassLoadHelper
*/
@Nullable
public static ResourceLoader getConfigTimeResourceLoader() {
return configTimeResourceLoaderHolder.get();
}
@@ -127,6 +129,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
* @see #setTaskExecutor
* @see LocalTaskExecutorThreadPool
*/
@Nullable
public static Executor getConfigTimeTaskExecutor() {
return configTimeTaskExecutorHolder.get();
}
@@ -140,6 +143,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
* @see #setDataSource
* @see LocalDataSourceJobStore
*/
@Nullable
public static DataSource getConfigTimeDataSource() {
return configTimeDataSourceHolder.get();
}
@@ -153,6 +157,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
* @see #setNonTransactionalDataSource
* @see LocalDataSourceJobStore
*/
@Nullable
public static DataSource getConfigTimeNonTransactionalDataSource() {
return configTimeNonTransactionalDataSourceHolder.get();
}
@@ -578,14 +583,14 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
* @see #afterPropertiesSet
* @see org.quartz.SchedulerFactory#getScheduler
*/
protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String schedulerName)
protected Scheduler createScheduler(SchedulerFactory schedulerFactory, @Nullable String schedulerName)
throws SchedulerException {
// Override thread context ClassLoader to work around naive Quartz ClassLoadHelper loading.
Thread currentThread = Thread.currentThread();
ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
boolean overrideClassLoader = (this.resourceLoader != null &&
!this.resourceLoader.getClassLoader().equals(threadContextClassLoader));
this.resourceLoader.getClassLoader() != threadContextClassLoader);
if (overrideClassLoader) {
currentThread.setContextClassLoader(this.resourceLoader.getClassLoader());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 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.
@@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.lang.Nullable;
/**
* FreeMarker {@link TemplateLoader} adapter that loads via a Spring {@link ResourceLoader}.
@@ -65,6 +66,7 @@ public class SpringTemplateLoader implements TemplateLoader {
@Override
@Nullable
public Object findTemplateSource(String name) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("Looking for FreeMarker template with name [" + name + "]");