@Nullable all the way: null-safety at field level

This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.

Issue: SPR-15720
This commit is contained in:
Juergen Hoeller
2017-06-30 01:53:45 +02:00
parent c4694c3f5c
commit cc74a2891a
936 changed files with 6090 additions and 2806 deletions

View File

@@ -93,15 +93,19 @@ public class JmsListenerAnnotationBeanPostProcessor
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private JmsListenerEndpointRegistry endpointRegistry;
@Nullable
private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME;
private final MessageHandlerMethodFactoryAdapter messageHandlerMethodFactory =
new MessageHandlerMethodFactoryAdapter();
@Nullable
private BeanFactory beanFactory;
@Nullable
private StringValueResolver embeddedValueResolver;
private final JmsListenerEndpointRegistrar registrar = new JmsListenerEndpointRegistrar();
@@ -296,10 +300,10 @@ public class JmsListenerAnnotationBeanPostProcessor
return new MethodJmsListenerEndpoint();
}
@Nullable
private String getEndpointId(JmsListener jmsListener) {
if (StringUtils.hasText(jmsListener.id())) {
return resolve(jmsListener.id());
String id = resolve(jmsListener.id());
return (id != null ? id : "");
}
else {
return "org.springframework.jms.JmsListenerEndpointContainer#" + this.counter.getAndIncrement();
@@ -320,6 +324,7 @@ public class JmsListenerAnnotationBeanPostProcessor
*/
private class MessageHandlerMethodFactoryAdapter implements MessageHandlerMethodFactory {
@Nullable
private MessageHandlerMethodFactory messageHandlerMethodFactory;
public void setMessageHandlerMethodFactory(MessageHandlerMethodFactory messageHandlerMethodFactory) {

View File

@@ -25,6 +25,7 @@ import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.support.QosSettings;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.lang.Nullable;
import org.springframework.util.ErrorHandler;
/**
@@ -39,32 +40,46 @@ public abstract class AbstractJmsListenerContainerFactory<C extends AbstractMess
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private ConnectionFactory connectionFactory;
@Nullable
private DestinationResolver destinationResolver;
@Nullable
private ErrorHandler errorHandler;
@Nullable
private MessageConverter messageConverter;
@Nullable
private Boolean sessionTransacted;
@Nullable
private Integer sessionAcknowledgeMode;
@Nullable
private Boolean pubSubDomain;
@Nullable
private Boolean replyPubSubDomain;
@Nullable
private QosSettings replyQosSettings;
@Nullable
private Boolean subscriptionDurable;
@Nullable
private Boolean subscriptionShared;
@Nullable
private String clientId;
@Nullable
private Integer phase;
@Nullable
private Boolean autoStartup;

View File

@@ -35,18 +35,22 @@ import org.springframework.lang.Nullable;
*/
public abstract class AbstractJmsListenerEndpoint implements JmsListenerEndpoint {
private String id;
private String id = "";
@Nullable
private String destination;
@Nullable
private String subscription;
@Nullable
private String selector;
@Nullable
private String concurrency;
public void setId(@Nullable String id) {
public void setId(String id) {
this.id = id;
}

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.
@@ -22,6 +22,7 @@ import org.springframework.jms.listener.endpoint.JmsActivationSpecConfig;
import org.springframework.jms.listener.endpoint.JmsActivationSpecFactory;
import org.springframework.jms.listener.endpoint.JmsMessageEndpointManager;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.lang.Nullable;
/**
* A {@link JmsListenerContainerFactory} implementation to build a
@@ -33,14 +34,19 @@ import org.springframework.jms.support.destination.DestinationResolver;
public class DefaultJcaListenerContainerFactory extends JmsActivationSpecConfig
implements JmsListenerContainerFactory<JmsMessageEndpointManager> {
@Nullable
private ResourceAdapter resourceAdapter;
@Nullable
private JmsActivationSpecFactory activationSpecFactory;
@Nullable
private DestinationResolver destinationResolver;
@Nullable
private Object transactionManager;
@Nullable
private Integer phase;

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.
@@ -19,6 +19,7 @@ package org.springframework.jms.config;
import java.util.concurrent.Executor;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.lang.Nullable;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.backoff.BackOff;
@@ -35,22 +36,31 @@ import org.springframework.util.backoff.BackOff;
public class DefaultJmsListenerContainerFactory
extends AbstractJmsListenerContainerFactory<DefaultMessageListenerContainer> {
@Nullable
private Executor taskExecutor;
@Nullable
private PlatformTransactionManager transactionManager;
@Nullable
private Integer cacheLevel;
@Nullable
private String cacheLevelName;
@Nullable
private String concurrency;
@Nullable
private Integer maxMessagesPerTask;
@Nullable
private Long receiveTimeout;
@Nullable
private Long recoveryInterval;
@Nullable
private BackOff backOff;

View File

@@ -38,14 +38,19 @@ import org.springframework.util.Assert;
*/
public class JmsListenerEndpointRegistrar implements BeanFactoryAware, InitializingBean {
@Nullable
private JmsListenerEndpointRegistry endpointRegistry;
@Nullable
private MessageHandlerMethodFactory messageHandlerMethodFactory;
@Nullable
private JmsListenerContainerFactory<?> containerFactory;
@Nullable
private String containerFactoryBeanName;
@Nullable
private BeanFactory beanFactory;
private final List<JmsListenerEndpointDescriptor> endpointDescriptors = new ArrayList<>();
@@ -131,6 +136,7 @@ public class JmsListenerEndpointRegistrar implements BeanFactoryAware, Initializ
}
protected void registerAllEndpoints() {
Assert.state(this.endpointRegistry != null, "No JmsListenerEndpointRegistry set");
synchronized (this.mutex) {
for (JmsListenerEndpointDescriptor descriptor : this.endpointDescriptors) {
this.endpointRegistry.registerListenerContainer(
@@ -168,7 +174,7 @@ public class JmsListenerEndpointRegistrar implements BeanFactoryAware, Initializ
* used for that endpoint.
*/
public void registerEndpoint(JmsListenerEndpoint endpoint, @Nullable JmsListenerContainerFactory<?> factory) {
Assert.notNull(endpoint, "Endpoint must be set");
Assert.notNull(endpoint, "Endpoint must not be null");
Assert.hasText(endpoint.getId(), "Endpoint id must be set");
// Factory may be null, we defer the resolution right before actually creating the container
@@ -176,6 +182,7 @@ public class JmsListenerEndpointRegistrar implements BeanFactoryAware, Initializ
synchronized (this.mutex) {
if (this.startImmediately) { // register and start immediately
Assert.state(this.endpointRegistry != null, "No JmsListenerEndpointRegistry set");
this.endpointRegistry.registerListenerContainer(descriptor.endpoint,
resolveContainerFactory(descriptor), true);
}
@@ -200,10 +207,12 @@ public class JmsListenerEndpointRegistrar implements BeanFactoryAware, Initializ
public final JmsListenerEndpoint endpoint;
@Nullable
public final JmsListenerContainerFactory<?> containerFactory;
public JmsListenerEndpointDescriptor(JmsListenerEndpoint endpoint,
@Nullable JmsListenerContainerFactory<?> containerFactory) {
this.endpoint = endpoint;
this.containerFactory = containerFactory;
}

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.
@@ -68,6 +68,7 @@ public class JmsListenerEndpointRegistry implements DisposableBean, SmartLifecyc
private int phase = Integer.MAX_VALUE;
@Nullable
private ApplicationContext applicationContext;
private boolean contextRefreshed;
@@ -133,9 +134,9 @@ public class JmsListenerEndpointRegistry implements DisposableBean, SmartLifecyc
Assert.notNull(endpoint, "Endpoint must not be null");
Assert.notNull(factory, "Factory must not be null");
String id = endpoint.getId();
Assert.notNull(id, "Endpoint id must not be null");
Assert.hasText(id, "Endpoint id must be set");
synchronized (this.listenerContainers) {
if (this.listenerContainers.containsKey(id)) {
throw new IllegalStateException("Another endpoint is already registered with id '" + id + "'");

View File

@@ -49,14 +49,19 @@ import org.springframework.util.StringValueResolver;
*/
public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint implements BeanFactoryAware {
@Nullable
private Object bean;
@Nullable
private Method method;
@Nullable
private Method mostSpecificMethod;
@Nullable
private MessageHandlerMethodFactory messageHandlerMethodFactory;
@Nullable
private StringValueResolver embeddedValueResolver;
@@ -67,6 +72,7 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint imple
this.bean = bean;
}
@Nullable
public Object getBean() {
return this.bean;
}
@@ -78,6 +84,7 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint imple
this.method = method;
}
@Nullable
public Method getMethod() {
return this.method;
}
@@ -92,16 +99,18 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint imple
this.mostSpecificMethod = mostSpecificMethod;
}
@Nullable
public Method getMostSpecificMethod() {
if (this.mostSpecificMethod != null) {
return this.mostSpecificMethod;
}
else if (AopUtils.isAopProxy(this.bean)) {
Method method = getMethod();
if (method != null && AopUtils.isAopProxy(this.bean)) {
Class<?> target = AopProxyUtils.ultimateTargetClass(this.bean);
return AopUtils.getMostSpecificMethod(getMethod(), target);
return AopUtils.getMostSpecificMethod(method, target);
}
else {
return getMethod();
return method;
}
}
@@ -117,7 +126,7 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint imple
/**
* Set a value resolver for embedded placeholders and expressions.
*/
public void setEmbeddedValueResolver(StringValueResolver embeddedValueResolver) {
public void setEmbeddedValueResolver(@Nullable StringValueResolver embeddedValueResolver) {
this.embeddedValueResolver = embeddedValueResolver;
}
@@ -178,6 +187,9 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint imple
@Nullable
protected String getDefaultResponseDestination() {
Method specificMethod = getMostSpecificMethod();
if (specificMethod == null) {
return null;
}
SendTo ann = getSendTo(specificMethod);
if (ann != null) {
Object[] destinations = ann.value();

View File

@@ -31,6 +31,7 @@ import org.springframework.util.Assert;
*/
public class SimpleJmsListenerEndpoint extends AbstractJmsListenerEndpoint {
@Nullable
private MessageListener messageListener;

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.
@@ -26,6 +26,8 @@ import javax.jms.QueueSender;
import javax.jms.Topic;
import javax.jms.TopicPublisher;
import org.springframework.lang.Nullable;
/**
* JMS MessageProducer decorator that adapts calls to a shared MessageProducer
* instance underneath, managing QoS settings locally within the decorator.
@@ -37,10 +39,13 @@ class CachedMessageProducer implements MessageProducer, QueueSender, TopicPublis
private final MessageProducer target;
@Nullable
private Boolean originalDisableMessageID;
@Nullable
private Boolean originalDisableMessageTimestamp;
@Nullable
private Long originalDeliveryDelay;
private int deliveryMode;

View File

@@ -491,6 +491,7 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
private final Destination destination;
@Nullable
private String destinationString;
public DestinationCacheKey(Destination destination) {
@@ -544,10 +545,13 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
*/
private static class ConsumerCacheKey extends DestinationCacheKey {
@Nullable
private final String selector;
@Nullable
private final Boolean noLocal;
@Nullable
private final String subscription;
private final boolean durable;

View File

@@ -53,6 +53,7 @@ public class JmsResourceHolder extends ResourceHolderSupport {
private static final Log logger = LogFactory.getLog(JmsResourceHolder.class);
@Nullable
private ConnectionFactory connectionFactory;
private boolean frozen = false;

View File

@@ -93,6 +93,7 @@ import org.springframework.util.Assert;
public class JmsTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
@Nullable
private ConnectionFactory connectionFactory;
@@ -327,6 +328,7 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
*/
private static class JmsTransactionObject implements SmartTransactionObject {
@Nullable
private JmsResourceHolder resourceHolder;
public void setResourceHolder(@Nullable JmsResourceHolder resourceHolder) {
@@ -344,7 +346,7 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
@Override
public boolean isRollbackOnly() {
return this.resourceHolder.isRollbackOnly();
return (this.resourceHolder != null && this.resourceHolder.isRollbackOnly());
}
@Override

View File

@@ -82,21 +82,27 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private ConnectionFactory targetConnectionFactory;
@Nullable
private String clientId;
@Nullable
private ExceptionListener exceptionListener;
private boolean reconnectOnException = false;
/** The target Connection */
@Nullable
private Connection connection;
/** A hint whether to create a queue or topic connection */
@Nullable
private Boolean pubSubMode;
/** An internal aggregator allowing for per-connection ExceptionListeners */
@Nullable
private AggregatedExceptionListener aggregatedExceptionListener;
/** Whether the shared Connection has been started */
@@ -525,6 +531,7 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti
*/
private class SharedConnectionInvocationHandler implements InvocationHandler {
@Nullable
private ExceptionListener localExceptionListener;
private boolean locallyStarted = false;

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 javax.jms.TopicConnectionFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -71,10 +72,13 @@ import org.springframework.util.StringUtils;
public class UserCredentialsConnectionFactoryAdapter
implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, InitializingBean {
@Nullable
private ConnectionFactory targetConnectionFactory;
@Nullable
private String username;
@Nullable
private String password;
private final ThreadLocal<JmsUserCredentials> threadBoundCredentials =
@@ -173,7 +177,7 @@ public class UserCredentialsConnectionFactoryAdapter
* @see javax.jms.ConnectionFactory#createConnection(String, String)
* @see javax.jms.ConnectionFactory#createConnection()
*/
protected Connection doCreateConnection(String username, String password) throws JMSException {
protected Connection doCreateConnection(@Nullable String username, @Nullable String password) throws JMSException {
ConnectionFactory target = obtainTargetConnectionFactory();
if (StringUtils.hasLength(username)) {
return target.createConnection(username, password);
@@ -219,7 +223,9 @@ public class UserCredentialsConnectionFactoryAdapter
* @see javax.jms.QueueConnectionFactory#createQueueConnection(String, String)
* @see javax.jms.QueueConnectionFactory#createQueueConnection()
*/
protected QueueConnection doCreateQueueConnection(String username, String password) throws JMSException {
protected QueueConnection doCreateQueueConnection(
@Nullable String username, @Nullable String password) throws JMSException {
ConnectionFactory target = obtainTargetConnectionFactory();
if (!(target instanceof QueueConnectionFactory)) {
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory");
@@ -269,7 +275,9 @@ public class UserCredentialsConnectionFactoryAdapter
* @see javax.jms.TopicConnectionFactory#createTopicConnection(String, String)
* @see javax.jms.TopicConnectionFactory#createTopicConnection()
*/
protected TopicConnection doCreateTopicConnection(String username, String password) throws JMSException {
protected TopicConnection doCreateTopicConnection(
@Nullable String username, @Nullable String password) throws JMSException {
ConnectionFactory target = obtainTargetConnectionFactory();
if (!(target instanceof TopicConnectionFactory)) {
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory");

View File

@@ -47,10 +47,12 @@ import org.springframework.util.Assert;
public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
implements JmsMessageOperations, InitializingBean {
@Nullable
private JmsTemplate jmsTemplate;
private MessageConverter jmsMessageConverter = new MessagingMessageConverter();
@Nullable
private String defaultDestinationName;
@@ -111,6 +113,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
/**
* Return the configured {@link JmsTemplate}.
*/
@Nullable
public JmsTemplate getJmsTemplate() {
return this.jmsTemplate;
}
@@ -158,7 +161,12 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
@Override
public void afterPropertiesSet() {
Assert.notNull(getJmsTemplate(), "Property 'connectionFactory' or 'jmsTemplate' is required");
Assert.notNull(this.jmsTemplate, "Property 'connectionFactory' or 'jmsTemplate' is required");
}
private JmsTemplate obtainJmsTemplate() {
Assert.state(this.jmsTemplate != null, "No JmsTemplate set");
return this.jmsTemplate;
}
@@ -325,7 +333,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
@Override
protected void doSend(Destination destination, Message<?> message) {
try {
this.jmsTemplate.send(destination, createMessageCreator(message));
obtainJmsTemplate().send(destination, createMessageCreator(message));
}
catch (JmsException ex) {
throw convertJmsException(ex);
@@ -334,7 +342,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
protected void doSend(String destinationName, Message<?> message) {
try {
this.jmsTemplate.send(destinationName, createMessageCreator(message));
obtainJmsTemplate().send(destinationName, createMessageCreator(message));
}
catch (JmsException ex) {
throw convertJmsException(ex);
@@ -344,7 +352,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
@Override
protected Message<?> doReceive(Destination destination) {
try {
javax.jms.Message jmsMessage = this.jmsTemplate.receive(destination);
javax.jms.Message jmsMessage = obtainJmsTemplate().receive(destination);
return convertJmsMessage(jmsMessage);
}
catch (JmsException ex) {
@@ -355,7 +363,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
@Nullable
protected Message<?> doReceive(String destinationName) {
try {
javax.jms.Message jmsMessage = this.jmsTemplate.receive(destinationName);
javax.jms.Message jmsMessage = obtainJmsTemplate().receive(destinationName);
return convertJmsMessage(jmsMessage);
}
catch (JmsException ex) {
@@ -366,7 +374,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
@Override
protected Message<?> doSendAndReceive(Destination destination, Message<?> requestMessage) {
try {
javax.jms.Message jmsMessage = this.jmsTemplate.sendAndReceive(
javax.jms.Message jmsMessage = obtainJmsTemplate().sendAndReceive(
destination, createMessageCreator(requestMessage));
return convertJmsMessage(jmsMessage);
}
@@ -378,7 +386,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
@Nullable
protected Message<?> doSendAndReceive(String destinationName, Message<?> requestMessage) {
try {
javax.jms.Message jmsMessage = this.jmsTemplate.sendAndReceive(
javax.jms.Message jmsMessage = obtainJmsTemplate().sendAndReceive(
destinationName, createMessageCreator(requestMessage));
return convertJmsMessage(jmsMessage);
}

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,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.lang.Nullable;
/**
* Convenient super class for application classes that need JMS access.
@@ -45,6 +46,7 @@ public abstract class JmsGatewaySupport implements InitializingBean {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private JmsTemplate jmsTemplate;
@@ -89,6 +91,7 @@ public abstract class JmsGatewaySupport implements InitializingBean {
/**
* Return the JmsTemplate for the gateway.
*/
@Nullable
public final JmsTemplate getJmsTemplate() {
return this.jmsTemplate;
}

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,14 +61,17 @@ import org.springframework.util.ClassUtils;
public abstract class AbstractJmsListeningContainer extends JmsDestinationAccessor
implements BeanNameAware, DisposableBean, SmartLifecycle {
@Nullable
private String clientId;
private boolean autoStartup = true;
private int phase = Integer.MAX_VALUE;
@Nullable
private String beanName;
@Nullable
private Connection sharedConnection;
private boolean sharedConnectionStarted = false;

View File

@@ -143,28 +143,37 @@ import org.springframework.util.ErrorHandler;
public abstract class AbstractMessageListenerContainer extends AbstractJmsListeningContainer
implements MessageListenerContainer {
@Nullable
private volatile Object destination;
@Nullable
private volatile String messageSelector;
@Nullable
private volatile Object messageListener;
private boolean subscriptionDurable = false;
private boolean subscriptionShared = false;
@Nullable
private String subscriptionName;
@Nullable
private Boolean replyPubSubDomain;
@Nullable
private QosSettings replyQosSettings;
private boolean pubSubNoLocal = false;
@Nullable
private MessageConverter messageConverter;
@Nullable
private ExceptionListener exceptionListener;
@Nullable
private ErrorHandler errorHandler;
private boolean exposeListenerSession = true;
@@ -238,7 +247,8 @@ public abstract class AbstractMessageListenerContainer extends AbstractJmsListen
* (never {@code null}).
*/
protected String getDestinationDescription() {
return this.destination.toString();
Object destination = this.destination;
return (destination != null ? destination.toString() : "");
}
/**

View File

@@ -87,6 +87,7 @@ public abstract class AbstractPollingMessageListenerContainer extends AbstractMe
private boolean sessionTransactedCalled = false;
@Nullable
private PlatformTransactionManager transactionManager;
private DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
@@ -232,7 +233,8 @@ public abstract class AbstractPollingMessageListenerContainer extends AbstractMe
* @throws JMSException if thrown by JMS methods
* @see #doReceiveAndExecute
*/
protected boolean receiveAndExecute(Object invoker, Session session, MessageConsumer consumer)
protected boolean receiveAndExecute(
Object invoker, @Nullable Session session, @Nullable MessageConsumer consumer)
throws JMSException {
if (this.transactionManager != null) {
@@ -242,18 +244,10 @@ public abstract class AbstractPollingMessageListenerContainer extends AbstractMe
try {
messageReceived = doReceiveAndExecute(invoker, session, consumer, status);
}
catch (JMSException ex) {
rollbackOnException(status, ex);
catch (JMSException | RuntimeException | Error ex) {
rollbackOnException(this.transactionManager, status, ex);
throw ex;
}
catch (RuntimeException ex) {
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
rollbackOnException(status, err);
throw err;
}
this.transactionManager.commit(status);
return messageReceived;
}
@@ -398,10 +392,10 @@ public abstract class AbstractPollingMessageListenerContainer extends AbstractMe
* @param status object representing the transaction
* @param ex the thrown listener exception or error
*/
private void rollbackOnException(TransactionStatus status, Throwable ex) {
private void rollbackOnException(PlatformTransactionManager manager, TransactionStatus status, Throwable ex) {
logger.debug("Initiating transaction rollback on listener exception", ex);
try {
this.transactionManager.rollback(status);
manager.rollback(status);
}
catch (RuntimeException ex2) {
logger.error("Listener exception overridden by rollback exception", ex);

View File

@@ -31,6 +31,7 @@ import org.springframework.jms.JmsException;
import org.springframework.jms.support.JmsUtils;
import org.springframework.jms.support.destination.CachingDestinationResolver;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.SchedulingAwareRunnable;
import org.springframework.scheduling.SchedulingTaskExecutor;
import org.springframework.util.Assert;
@@ -173,6 +174,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
private static final Constants constants = new Constants(DefaultMessageListenerContainer.class);
@Nullable
private Executor taskExecutor;
private BackOff backOff = new FixedBackOff(DEFAULT_RECOVERY_INTERVAL, Long.MAX_VALUE);
@@ -199,6 +201,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
private volatile boolean interrupted = false;
@Nullable
private Runnable stopCallback;
private Object currentRecoveryMarker = new Object();
@@ -717,6 +720,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
*/
@Override
protected void doRescheduleTask(Object task) {
Assert.state(this.taskExecutor != null, "No TaskExecutor available");
this.taskExecutor.execute((Runnable) task);
}
@@ -1031,10 +1035,13 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
*/
private class AsyncMessageListenerInvoker implements SchedulingAwareRunnable {
@Nullable
private Session session;
@Nullable
private MessageConsumer consumer;
@Nullable
private Object lastRecoveryMarker;
private boolean lastMessageSucceeded;

View File

@@ -29,6 +29,7 @@ import javax.jms.MessageConsumer;
import javax.jms.Session;
import org.springframework.jms.support.JmsUtils;
import org.springframework.lang.Nullable;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
@@ -67,10 +68,13 @@ public class SimpleMessageListenerContainer extends AbstractMessageListenerConta
private int concurrentConsumers = 1;
@Nullable
private Executor taskExecutor;
@Nullable
private Set<Session> sessions;
@Nullable
private Set<MessageConsumer> consumers;
private final Object consumersMonitor = new Object();
@@ -335,9 +339,11 @@ public class SimpleMessageListenerContainer extends AbstractMessageListenerConta
for (MessageConsumer consumer : this.consumers) {
JmsUtils.closeMessageConsumer(consumer);
}
logger.debug("Closing JMS Sessions");
for (Session session : this.sessions) {
JmsUtils.closeSession(session);
if (this.sessions != null) {
logger.debug("Closing JMS Sessions");
for (Session session : this.sessions) {
JmsUtils.closeSession(session);
}
}
}
}

View File

@@ -60,6 +60,7 @@ public abstract class AbstractAdaptableMessageListener
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private Object defaultResponseDestination;
private DestinationResolver destinationResolver = new DynamicDestinationResolver();
@@ -68,6 +69,7 @@ public abstract class AbstractAdaptableMessageListener
private final MessagingMessageConverterAdapter messagingMessageConverter = new MessagingMessageConverterAdapter();
@Nullable
private QosSettings responseQosSettings;
@@ -504,8 +506,10 @@ public abstract class AbstractAdaptableMessageListener
private final javax.jms.Message message;
@Nullable
private Object payload;
@Nullable
private MessageHeaders headers;
public LazyResolutionMessage(javax.jms.Message message) {

View File

@@ -44,22 +44,28 @@ public class JmsActivationSpecConfig {
private static final Constants sessionConstants = new Constants(Session.class);
@Nullable
private String destinationName;
private boolean pubSubDomain = false;
@Nullable
private Boolean replyPubSubDomain;
@Nullable
private QosSettings replyQosSettings;
private boolean subscriptionDurable = false;
private boolean subscriptionShared = false;
@Nullable
private String subscriptionName;
@Nullable
private String clientId;
@Nullable
private String messageSelector;
private int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
@@ -68,6 +74,7 @@ public class JmsActivationSpecConfig {
private int prefetchSize = -1;
@Nullable
private MessageConverter messageConverter;
@@ -75,6 +82,7 @@ public class JmsActivationSpecConfig {
this.destinationName = destinationName;
}
@Nullable
public String getDestinationName() {
return this.destinationName;
}
@@ -104,6 +112,7 @@ public class JmsActivationSpecConfig {
this.replyQosSettings = replyQosSettings;
}
@Nullable
public QosSettings getReplyQosSettings() {
return this.replyQosSettings;
}

View File

@@ -60,6 +60,7 @@ public class JmsMessageEndpointManager extends GenericMessageEndpointManager
private JmsActivationSpecFactory activationSpecFactory = new DefaultJmsActivationSpecFactory();
@Nullable
private JmsActivationSpecConfig activationSpecConfig;

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.
@@ -51,10 +51,13 @@ import org.springframework.lang.Nullable;
*/
public class StandardJmsActivationSpecFactory implements JmsActivationSpecFactory {
@Nullable
private Class<?> activationSpecClass;
@Nullable
private Map<String, String> defaultProperties;
@Nullable
private DestinationResolver destinationResolver;
@@ -87,7 +90,7 @@ public class StandardJmsActivationSpecFactory implements JmsActivationSpecFactor
* or {@link org.springframework.jms.support.destination.BeanFactoryDestinationResolver}
* but not {@link org.springframework.jms.support.destination.DynamicDestinationResolver}.
*/
public void setDestinationResolver(@Nullable DestinationResolver destinationResolver) {
public void setDestinationResolver(DestinationResolver destinationResolver) {
this.destinationResolver = destinationResolver;
}
@@ -142,26 +145,28 @@ public class StandardJmsActivationSpecFactory implements JmsActivationSpecFactor
*/
protected void populateActivationSpecProperties(BeanWrapper bw, JmsActivationSpecConfig config) {
String destinationName = config.getDestinationName();
boolean pubSubDomain = config.isPubSubDomain();
Object destination = destinationName;
if (this.destinationResolver != null) {
try {
destination = this.destinationResolver.resolveDestinationName(null, destinationName, pubSubDomain);
}
catch (JMSException ex) {
throw new DestinationResolutionException("Cannot resolve destination name [" + destinationName + "]", ex);
if (destinationName != null) {
boolean pubSubDomain = config.isPubSubDomain();
Object destination = destinationName;
if (this.destinationResolver != null) {
try {
destination = this.destinationResolver.resolveDestinationName(null, destinationName, pubSubDomain);
}
catch (JMSException ex) {
throw new DestinationResolutionException(
"Cannot resolve destination name [" + destinationName + "]", ex);
}
}
bw.setPropertyValue("destination", destination);
bw.setPropertyValue("destinationType", pubSubDomain ? Topic.class.getName() : Queue.class.getName());
}
bw.setPropertyValue("destination", destination);
bw.setPropertyValue("destinationType", pubSubDomain ? Topic.class.getName() : Queue.class.getName());
if (bw.isWritableProperty("subscriptionDurability")) {
bw.setPropertyValue("subscriptionDurability", config.isSubscriptionDurable() ? "Durable" : "NonDurable");
}
else if (config.isSubscriptionDurable()) {
// Standard JCA 1.5 "subscriptionDurability" apparently not supported...
throw new IllegalArgumentException(
"Durable subscriptions not supported by underlying provider: " + this.activationSpecClass.getName());
throw new IllegalArgumentException("Durable subscriptions not supported by underlying provider");
}
if (config.isSubscriptionShared()) {
throw new IllegalArgumentException("Shared subscriptions not supported for JCA-driven endpoints");
@@ -208,8 +213,7 @@ public class StandardJmsActivationSpecFactory implements JmsActivationSpecFactor
}
else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE) {
// Standard JCA 1.5 "acknowledgeMode" apparently not supported (e.g. WebSphere MQ 6.0.2.1)
throw new IllegalArgumentException(
"Dups-ok-acknowledge not supported by underlying provider: " + this.activationSpecClass.getName());
throw new IllegalArgumentException("Dups-ok-acknowledge not supported by underlying provider");
}
}

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.
@@ -74,8 +74,10 @@ import org.springframework.util.Assert;
*/
public class JmsInvokerClientInterceptor implements MethodInterceptor, InitializingBean {
@Nullable
private ConnectionFactory connectionFactory;
@Nullable
private Object queue;
private DestinationResolver destinationResolver = new DynamicDestinationResolver();

View File

@@ -19,6 +19,7 @@ package org.springframework.jms.remoting;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -44,10 +45,13 @@ import org.springframework.util.ClassUtils;
public class JmsInvokerProxyFactoryBean extends JmsInvokerClientInterceptor
implements FactoryBean<Object>, BeanClassLoaderAware {
@Nullable
private Class<?> serviceInterface;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@Nullable
private Object serviceProxy;

View File

@@ -76,14 +76,17 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B
private String encoding = DEFAULT_ENCODING;
@Nullable
private String encodingPropertyName;
@Nullable
private String typeIdPropertyName;
private Map<String, Class<?>> idClassMappings = new HashMap<>();
private Map<Class<?>, String> classIdMappings = new HashMap<>();
@Nullable
private ClassLoader beanClassLoader;

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.
@@ -38,6 +38,7 @@ import org.springframework.util.Assert;
*/
public class BeanFactoryDestinationResolver implements DestinationResolver, BeanFactoryAware {
@Nullable
private BeanFactory beanFactory;