From 218daa94e8bee3136a17acce64cc80f769b56dc6 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Wed, 1 Feb 2017 12:45:01 -0500 Subject: [PATCH] INT-4222: Don't Propagate a null ConversionService JIRA: https://jira.spring.io/browse/INT-4222 See INT-4214; the `DefaultMessageHandlerMethodFactory` requires a conversion service and sets up a default. Some SI components propagated a `null` conversion service which overwrote the default causing runtime exceptions. Caused by: java.lang.IllegalArgumentException: ConversionService must not be null at org.springframework.util.Assert.notNull(Assert.java:163) ~[spring-core-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT] --- .../integration/filter/MessageFilter.java | 8 ++++++-- .../integration/gateway/GatewayProxyFactoryBean.java | 4 ++-- .../handler/ServiceActivatingHandler.java | 8 ++++++-- .../router/AbstractMappingMessageRouter.java | 6 +++--- .../router/AbstractMessageProcessingRouter.java | 6 +++++- .../integration/router/AbstractMessageRouter.java | 8 ++++---- .../splitter/AbstractMessageProcessingSplitter.java | 2 +- .../transformer/MapToObjectTransformer.java | 4 ++-- .../util/MessagingMethodInvokerHelper.java | 4 +++- .../integration/jms/JmsOutboundGateway.java | 12 +++++++++--- .../integration/jms/JmsSendingMessageHandler.java | 8 ++++++-- 11 files changed, 47 insertions(+), 23 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/filter/MessageFilter.java b/spring-integration-core/src/main/java/org/springframework/integration/filter/MessageFilter.java index dfadaca8b8..69734d2966 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/filter/MessageFilter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/filter/MessageFilter.java @@ -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. @@ -18,6 +18,7 @@ package org.springframework.integration.filter; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.context.Lifecycle; +import org.springframework.core.convert.ConversionService; import org.springframework.integration.MessageRejectedException; import org.springframework.integration.core.MessageSelector; import org.springframework.integration.handler.AbstractReplyProducingPostProcessingMessageHandler; @@ -130,7 +131,10 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa Assert.state(!(this.discardChannelName != null && this.discardChannel != null), "'discardChannelName' and 'discardChannel' are mutually exclusive."); if (this.selector instanceof AbstractMessageProcessingSelector) { - ((AbstractMessageProcessingSelector) this.selector).setConversionService(this.getConversionService()); + ConversionService conversionService = getConversionService(); + if (conversionService != null) { + ((AbstractMessageProcessingSelector) this.selector).setConversionService(conversionService); + } } if (this.selector instanceof BeanFactoryAware && this.getBeanFactory() != null) { ((BeanFactoryAware) this.selector).setBeanFactory(this.getBeanFactory()); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java index c1377f88cd..c23d630e76 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java @@ -630,8 +630,8 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint if (Mono.class.isAssignableFrom(expectedReturnType)) { return (T) source; } - if (this.getConversionService() != null) { - return this.getConversionService().convert(source, expectedReturnType); + if (getConversionService() != null) { + return getConversionService().convert(source, expectedReturnType); } else { return this.typeConverter.convertIfNecessary(source, expectedReturnType); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/ServiceActivatingHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/ServiceActivatingHandler.java index e4b02b4bde..d1b267d470 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/ServiceActivatingHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/ServiceActivatingHandler.java @@ -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. @@ -20,6 +20,7 @@ import java.lang.reflect.Method; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.context.Lifecycle; +import org.springframework.core.convert.ConversionService; import org.springframework.integration.annotation.ServiceActivator; import org.springframework.messaging.Message; @@ -58,7 +59,10 @@ public class ServiceActivatingHandler extends AbstractReplyProducingMessageHandl @Override protected void doInit() { if (this.processor instanceof AbstractMessageProcessor) { - ((AbstractMessageProcessor) this.processor).setConversionService(this.getConversionService()); + ConversionService conversionService = getConversionService(); + if (conversionService != null) { + ((AbstractMessageProcessor) this.processor).setConversionService(conversionService); + } } if (this.processor instanceof BeanFactoryAware && this.getBeanFactory() != null) { ((BeanFactoryAware) this.processor).setBeanFactory(this.getBeanFactory()); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java index d2daec83e9..6545620b04 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java @@ -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. @@ -292,8 +292,8 @@ public abstract class AbstractMappingMessageRouter extends AbstractMessageRouter else if (channelKey instanceof Collection) { addToCollection(channels, (Collection) channelKey, message); } - else if (this.getRequiredConversionService().canConvert(channelKey.getClass(), String.class)) { - addChannelFromString(channels, this.getConversionService().convert(channelKey, String.class), message); + else if (getRequiredConversionService().canConvert(channelKey.getClass(), String.class)) { + addChannelFromString(channels, getConversionService().convert(channelKey, String.class), message); } else { throw new MessagingException("unsupported return type for router [" + channelKey.getClass() + "]"); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java index dce1114150..ee2acfb795 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.context.Lifecycle; +import org.springframework.core.convert.ConversionService; import org.springframework.integration.handler.AbstractMessageProcessor; import org.springframework.integration.handler.MessageProcessor; import org.springframework.messaging.Message; @@ -49,7 +50,10 @@ class AbstractMessageProcessingRouter extends AbstractMappingMessageRouter public final void onInit() throws Exception { super.onInit(); if (this.messageProcessor instanceof AbstractMessageProcessor) { - ((AbstractMessageProcessor) this.messageProcessor).setConversionService(this.getConversionService()); + ConversionService conversionService = getConversionService(); + if (conversionService != null) { + ((AbstractMessageProcessor) this.messageProcessor).setConversionService(conversionService); + } } if (this.messageProcessor instanceof BeanFactoryAware && this.getBeanFactory() != null) { ((BeanFactoryAware) this.messageProcessor).setBeanFactory(this.getBeanFactory()); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java index 53e37543d4..81d365bf06 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java @@ -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. @@ -139,12 +139,12 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler imple protected ConversionService getRequiredConversionService() { if (this.getConversionService() == null) { synchronized (this) { - if (this.getConversionService() == null) { - this.setConversionService(DefaultConversionService.getSharedInstance()); + if (getConversionService() == null) { + setConversionService(DefaultConversionService.getSharedInstance()); } } } - return this.getConversionService(); + return getConversionService(); } @Override diff --git a/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageProcessingSplitter.java b/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageProcessingSplitter.java index 95d1429169..d9d7e4ece1 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageProcessingSplitter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageProcessingSplitter.java @@ -47,7 +47,7 @@ abstract class AbstractMessageProcessingSplitter extends AbstractMessageSplitter @Override protected void doInit() { - ConversionService conversionService = this.getConversionService(); + ConversionService conversionService = getConversionService(); if (conversionService != null && this.messageProcessor instanceof AbstractMessageProcessor) { ((AbstractMessageProcessor) this.messageProcessor).setConversionService(conversionService); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/MapToObjectTransformer.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/MapToObjectTransformer.java index 58b9840004..33066417a1 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/MapToObjectTransformer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/transformer/MapToObjectTransformer.java @@ -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. @@ -82,7 +82,7 @@ public class MapToObjectTransformer extends AbstractPayloadTransformer : this.getBeanFactory().getBean(this.targetBeanName); DataBinder binder = new DataBinder(target); - ConversionService conversionService = this.getConversionService(); + ConversionService conversionService = getConversionService(); if (conversionService == null) { conversionService = DefaultConversionService.getSharedInstance(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java b/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java index d311defa42..db7e563b7e 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java @@ -187,7 +187,9 @@ public class MessagingMethodInvokerHelper extends AbstractExpressionEvaluator @Override public void setConversionService(ConversionService conversionService) { super.setConversionService(conversionService); - this.messageHandlerMethodFactory.setConversionService(conversionService); + if (conversionService != null) { + this.messageHandlerMethodFactory.setConversionService(conversionService); + } } public T process(Message message) throws Exception { diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java index 2fc6e58a7d..fbb651444e 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java @@ -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. @@ -45,6 +45,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.Lifecycle; +import org.springframework.core.convert.ConversionService; import org.springframework.expression.Expression; import org.springframework.integration.IntegrationMessageHeaderAccessor; import org.springframework.integration.MessageTimeoutException; @@ -535,13 +536,18 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp ^ this.requestDestinationExpressionProcessor != null, "Exactly one of 'requestDestination', 'requestDestinationName', " + "or 'requestDestinationExpression' is required."); + ConversionService conversionService = getConversionService(); if (this.requestDestinationExpressionProcessor != null) { this.requestDestinationExpressionProcessor.setBeanFactory(getBeanFactory()); - this.requestDestinationExpressionProcessor.setConversionService(getConversionService()); + if (conversionService != null) { + this.requestDestinationExpressionProcessor.setConversionService(conversionService); + } } if (this.replyDestinationExpressionProcessor != null) { this.replyDestinationExpressionProcessor.setBeanFactory(getBeanFactory()); - this.replyDestinationExpressionProcessor.setConversionService(getConversionService()); + if (conversionService != null) { + this.replyDestinationExpressionProcessor.setConversionService(conversionService); + } } /* * This is needed because there is no way to detect 2 or more gateways using the same reply queue diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsSendingMessageHandler.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsSendingMessageHandler.java index 496501f986..3be922e9a1 100644 --- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsSendingMessageHandler.java +++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsSendingMessageHandler.java @@ -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. @@ -19,6 +19,7 @@ package org.springframework.integration.jms; import javax.jms.Destination; import javax.jms.JMSException; +import org.springframework.core.convert.ConversionService; import org.springframework.expression.Expression; import org.springframework.integration.IntegrationMessageHeaderAccessor; import org.springframework.integration.handler.AbstractMessageHandler; @@ -99,7 +100,10 @@ public class JmsSendingMessageHandler extends AbstractMessageHandler { protected void onInit() { if (this.destinationExpressionProcessor != null) { this.destinationExpressionProcessor.setBeanFactory(getBeanFactory()); - this.destinationExpressionProcessor.setConversionService(getConversionService()); + ConversionService conversionService = getConversionService(); + if (conversionService != null) { + this.destinationExpressionProcessor.setConversionService(conversionService); + } } }