From b187bca36e2565e80e72e662c204a57c05aab11d Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Thu, 7 Mar 2019 12:53:52 -0500 Subject: [PATCH] Avoid throws Exception where possible - Phase I * Polishing - PR Comments --- build.gradle | 2 +- gradle.properties | 1 + .../amqp/config/AmqpChannelFactoryBean.java | 134 ++++++---------- .../inbound/AmqpInboundChannelAdapter.java | 2 +- ...AmqpOutboundChannelAdapterParserTests.java | 2 +- .../AmqpOutboundGatewayParserTests.java | 2 +- .../AbstractCorrelatingMessageHandler.java | 11 +- .../aggregator/CorrelatingMessageBarrier.java | 4 +- .../integration/channel/NullChannel.java | 2 +- .../AbstractEvaluationContextFactoryBean.java | 6 +- .../config/ChannelInitializer.java | 4 +- .../config/ConsumerEndpointFactoryBean.java | 9 +- .../CorrelationStrategyFactoryBean.java | 9 +- ...tegrationEvaluationContextFactoryBean.java | 6 +- .../IntegrationManagementConfigurer.java | 6 +- ...ionSimpleEvaluationContextFactoryBean.java | 6 +- .../config/ReleaseStrategyFactoryBean.java | 6 +- ...ourcePollingChannelAdapterFactoryBean.java | 6 +- .../config/SpelFunctionFactoryBean.java | 6 +- .../config/annotation/Disposables.java | 12 +- .../context/ConverterRegistrar.java | 4 +- .../endpoint/AbstractEndpoint.java | 4 +- .../endpoint/AbstractMessageSource.java | 2 +- .../gateway/GatewayProxyFactoryBean.java | 6 +- .../handler/AbstractMessageHandler.java | 6 +- .../ExpressionEvaluatingMessageHandler.java | 4 +- .../handler/MessageHandlerChain.java | 8 +- .../advice/AbstractRequestHandlerAdvice.java | 27 ++-- .../advice/ErrorMessageSendingRecoverer.java | 4 +- ...ressionEvaluatingRequestHandlerAdvice.java | 17 +- .../RateLimiterRequestHandlerAdvice.java | 2 +- .../RequestHandlerCircuitBreakerAdvice.java | 11 +- .../advice/RequestHandlerRetryAdvice.java | 19 ++- .../handler/support/MapArgumentResolver.java | 4 +- .../PayloadExpressionArgumentResolver.java | 4 +- .../support/PayloadsArgumentResolver.java | 4 +- .../mapping/OutboundMessageMapper.java | 4 +- .../integration/util/JavaUtils.java | 105 +++++++++++++ .../integration/config/FilterParserTests.java | 2 +- .../FilterAnnotationPostProcessorTests.java | 2 +- ...MessagingAnnotationPostProcessorTests.java | 2 +- .../config/xml/EnricherParserTests.java | 2 +- .../config/xml/EnricherParserTests4.java | 2 +- .../xml/ServiceActivatorParserTests.java | 2 +- .../dsl/transformers/TransformerTests.java | 4 +- .../advice/AdvisedMessageHandlerTests.java | 23 +-- .../advice/IdempotentReceiverTests.java | 2 +- .../transformer/TransformerContextTests.java | 2 +- ...ventOutboundChannelAdapterParserTests.java | 2 +- ...eTailInboundChannelAdapterFactoryBean.java | 2 +- .../AbstractFilePayloadTransformer.java | 7 +- .../FileToByteArrayTransformer.java | 5 +- .../transformer/FileToStringTransformer.java | 5 +- ...FileOutboundChannelAdapterParserTests.java | 2 +- .../FtpOutboundChannelAdapterParserTests.java | 2 +- .../config/FtpOutboundGatewayParserTests.java | 2 +- ...fireOutboundChannelAdapterParserTests.java | 4 +- .../groovy/config/GroovyControlBusTests.java | 11 +- .../http/support/DefaultHttpHeaderMapper.java | 18 ++- ...HttpOutboundChannelAdapterParserTests.java | 2 +- .../HttpOutboundGatewayParserTests.java | 2 +- .../TcpConnectionFactoryFactoryBean.java | 5 +- .../ip/tcp/TcpOutboundGateway.java | 145 +++++++++++------- .../AbstractClientConnectionFactory.java | 16 +- .../connection/AbstractConnectionFactory.java | 45 +++--- .../AbstractServerConnectionFactory.java | 4 +- .../CachingClientConnectionFactory.java | 4 +- .../DefaultTcpNetConnectionSupport.java | 2 +- .../DefaultTcpNioConnectionSupport.java | 4 +- .../DefaultTcpNioSSLConnectionSupport.java | 5 +- .../FailoverClientConnectionFactory.java | 33 ++-- .../ip/tcp/connection/TcpConnection.java | 8 +- .../TcpConnectionInterceptorSupport.java | 6 +- .../TcpNetClientConnectionFactory.java | 29 ++-- .../ip/tcp/connection/TcpNetConnection.java | 128 +++++++++------- .../connection/TcpNetConnectionSupport.java | 5 +- .../TcpNetServerConnectionFactory.java | 10 +- .../TcpNioClientConnectionFactory.java | 54 ++++--- .../ip/tcp/connection/TcpNioConnection.java | 110 ++++++------- .../connection/TcpNioConnectionSupport.java | 5 +- .../tcp/connection/TcpNioSSLConnection.java | 14 +- .../TcpNioServerConnectionFactory.java | 83 +++++----- ...ThreadAffinityClientConnectionFactory.java | 8 +- .../ip/udp/DatagramPacketMessageMapper.java | 32 ++-- .../udp/MulticastSendingMessageHandler.java | 5 +- .../udp/UnicastReceivingChannelAdapter.java | 2 +- .../ip/udp/UnicastSendingMessageHandler.java | 7 +- .../integration/ip/util/TestingUtilities.java | 6 +- .../ip/config/ParserUnitTests.java | 2 +- .../ip/tcp/TcpOutboundGatewayTests.java | 32 ++-- .../CachingClientConnectionFactoryTests.java | 15 +- .../tcp/connection/ConnectionEventTests.java | 15 +- .../connection/ConnectionTimeoutTests.java | 2 +- .../FailoverClientConnectionFactoryTests.java | 45 +++--- .../tcp/connection/HelloWorldInterceptor.java | 16 +- .../ip/tcp/connection/SocketSupportTests.java | 33 +--- .../tcp/connection/TcpMessageMapperTests.java | 10 +- .../TcpNetConnectionSupportTests.java | 10 +- .../tcp/connection/TcpNetConnectionTests.java | 2 + .../tcp/connection/TcpNioConnectionTests.java | 5 +- .../ip/udp/UdpChannelAdapterTests.java | 2 +- .../config/JdbcMessageHandlerParserTests.java | 2 +- .../JdbcOutboundGatewayParserTests.java | 2 +- .../StoredProcMessageHandlerParserTests.java | 2 +- .../StoredProcOutboundGatewayParserTests.java | 2 +- .../JmsOutboundChannelAdapterParserTests.java | 2 +- .../config/JmsOutboundGatewayParserTests.java | 2 +- .../NotificationPublishingMessageHandler.java | 10 +- .../jmx/config/CustomObjectNameTests.java | 4 +- ...onPublishingChannelAdapterParserTests.java | 2 +- ...tionInvokingChannelAdapterParserTests.java | 2 +- ...OperationInvokingOutboundGatewayTests.java | 2 +- .../IdempotentReceiverIntegrationTests.java | 5 +- .../monitor/TransformerContextTests.java | 2 +- .../xml/JpaMessageHandlerParserTests.java | 2 +- .../MongoDbStoringMessageHandler.java | 4 +- .../outbound/AbstractMqttMessageHandler.java | 6 +- .../mqtt/outbound/MqttPahoMessageHandler.java | 24 +-- .../RedisQueueOutboundChannelAdapter.java | 4 +- .../config/RmiOutboundGatewayParserTests.java | 4 +- .../OutboundChannelAdapterParserTests.java | 2 +- .../SftpOutboundGatewayParserTests.java | 2 +- .../test/mock/MockMessageHandler.java | 6 +- .../WebSocketOutboundMessageHandler.java | 6 +- .../WebServiceOutboundGatewayParserTests.java | 2 +- .../ChatMessageSendingMessageHandler.java | 107 +++++++------ .../PresenceSendingMessageHandler.java | 20 ++- ...sageOutboundChannelAdapterParserTests.java | 2 +- ...enceOutboundChannelAdapterParserTests.java | 2 +- src/reference/asciidoc/handler-advice.adoc | 2 + 130 files changed, 992 insertions(+), 784 deletions(-) diff --git a/build.gradle b/build.gradle index a38cabdeeb..907facd597 100644 --- a/build.gradle +++ b/build.gradle @@ -261,7 +261,7 @@ subprojects { subproject -> } test { - maxHeapSize = "1024m" + maxHeapSize = "1536m" jacoco { append = false destinationFile = file("$buildDir/jacoco.exec") diff --git a/gradle.properties b/gradle.properties index c91267f063..43af26c1c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ version=5.2.0.BUILD-SNAPSHOT +org.gradle.jvmargs=-Xmx1536m diff --git a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/config/AmqpChannelFactoryBean.java b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/config/AmqpChannelFactoryBean.java index 5cd3d341b2..3af7eef76a 100644 --- a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/config/AmqpChannelFactoryBean.java +++ b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/config/AmqpChannelFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.springframework.amqp.core.AmqpTemplate; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.MessageDeliveryMode; import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.connection.RabbitAccessor; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer; import org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer; @@ -35,8 +36,6 @@ import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.rabbit.support.MessagePropertiesConverter; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.Lifecycle; import org.springframework.context.SmartLifecycle; @@ -46,15 +45,13 @@ import org.springframework.integration.amqp.channel.PollableAmqpChannel; import org.springframework.integration.amqp.channel.PublishSubscribeAmqpChannel; import org.springframework.integration.amqp.support.AmqpHeaderMapper; import org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper; +import org.springframework.integration.util.JavaUtils; import org.springframework.lang.Nullable; import org.springframework.messaging.support.ChannelInterceptor; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.interceptor.TransactionAttribute; import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; import org.springframework.util.ErrorHandler; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; /** * If point-to-point, we send to the default exchange with the routing key @@ -71,7 +68,7 @@ import org.springframework.util.StringUtils; * @since 2.1 */ public class AmqpChannelFactoryBean extends AbstractFactoryBean - implements SmartLifecycle, DisposableBean, BeanNameAware { + implements SmartLifecycle, BeanNameAware { private volatile AbstractAmqpChannel channel; @@ -355,32 +352,26 @@ public class AmqpChannelFactoryBean extends AbstractFactoryBean message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundGatewayParserTests.java b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundGatewayParserTests.java index 2eeda50036..8dae4a0816 100644 --- a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundGatewayParserTests.java +++ b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpOutboundGatewayParserTests.java @@ -328,7 +328,7 @@ public class AmqpOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aggregator/AbstractCorrelatingMessageHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/aggregator/AbstractCorrelatingMessageHandler.java index 04d8f04bc2..940cdef451 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aggregator/AbstractCorrelatingMessageHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aggregator/AbstractCorrelatingMessageHandler.java @@ -55,6 +55,7 @@ import org.springframework.integration.util.UUIDConverter; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageDeliveryException; +import org.springframework.messaging.MessageHandlingException; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -431,7 +432,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP } @Override - protected void handleMessageInternal(Message message) throws InterruptedException { + protected void handleMessageInternal(Message message) { Object correlationKey = this.correlationStrategy.getCorrelationKey(message); Assert.state(correlationKey != null, "Null correlation not allowed. Maybe the CorrelationStrategy is failing?"); @@ -444,7 +445,13 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP Lock lock = this.lockRegistry.obtain(groupIdUuid.toString()); boolean noOutput = true; - lock.lockInterruptibly(); + try { + lock.lockInterruptibly(); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new MessageHandlingException(message, "Interrupted getting lock", e); + } try { noOutput = processMessageForGroup(message, correlationKey, groupIdUuid, lock); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aggregator/CorrelatingMessageBarrier.java b/spring-integration-core/src/main/java/org/springframework/integration/aggregator/CorrelatingMessageBarrier.java index 21dbb1cb07..23b223e150 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aggregator/CorrelatingMessageBarrier.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aggregator/CorrelatingMessageBarrier.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -91,7 +91,7 @@ public class CorrelatingMessageBarrier extends AbstractMessageHandler implements } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { Object correlationKey = this.correlationStrategy.getCorrelationKey(message); Object lock = getLock(correlationKey); synchronized (lock) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java b/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java index 3702e609a7..4b2a980822 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java @@ -281,7 +281,7 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics, } @Override - public void destroy() throws Exception { + public void destroy() { if (this.successTimer != null) { this.successTimer.remove(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractEvaluationContextFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractEvaluationContextFactoryBean.java index 98aab74566..64e8f517b5 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractEvaluationContextFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractEvaluationContextFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2019 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. @@ -90,7 +90,7 @@ public abstract class AbstractEvaluationContextFactoryBean implements Applicatio return this.functions; } - protected void initialize(String beanName) throws Exception { + protected void initialize(String beanName) { if (this.applicationContext != null) { ConversionService conversionService = IntegrationUtils.getConversionService(getApplicationContext()); if (conversionService != null) { @@ -115,7 +115,7 @@ public abstract class AbstractEvaluationContextFactoryBean implements Applicatio } } } - catch (NoSuchBeanDefinitionException e) { + catch (@SuppressWarnings("unused") NoSuchBeanDefinitionException e) { // There is no 'SpelPropertyAccessorRegistrar' bean in the application context. } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/ChannelInitializer.java b/spring-integration-core/src/main/java/org/springframework/integration/config/ChannelInitializer.java index cb12a4940c..21e6563383 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/ChannelInitializer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/ChannelInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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 @@ final class ChannelInitializer implements BeanFactoryAware, InitializingBean { } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { Assert.notNull(this.beanFactory, "'beanFactory' must not be null"); if (!this.autoCreate) { return; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java index 11c9588e48..240a5ca17a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java @@ -182,7 +182,7 @@ public class ConsumerEndpointFactoryBean } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { if (this.beanName == null) { logger.error("The MessageHandler [" + this.handler + "] will be created without a 'componentName'. " + "Consider specifying the 'beanName' property on this ConsumerEndpointFactoryBean."); @@ -248,7 +248,7 @@ public class ConsumerEndpointFactoryBean } @Override - public AbstractEndpoint getObject() throws Exception { + public AbstractEndpoint getObject() { if (!this.initialized) { this.initializeEndpoint(); } @@ -263,8 +263,7 @@ public class ConsumerEndpointFactoryBean return this.endpoint.getClass(); } - @SuppressWarnings("unchecked") - private void initializeEndpoint() throws Exception { + private void initializeEndpoint() { synchronized (this.initializationMonitor) { if (this.initialized) { return; @@ -381,7 +380,7 @@ public class ConsumerEndpointFactoryBean } @Override - public void destroy() throws Exception { + public void destroy() { if (this.endpoint != null) { this.endpoint.destroy(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java index b8bcdfa374..9a95cc75b2 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -56,7 +56,7 @@ public class CorrelationStrategyFactoryBean implements FactoryBean getObjectType() { return CorrelationStrategy.class; } + @Override public boolean isSingleton() { return true; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationEvaluationContextFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationEvaluationContextFactoryBean.java index b776b6a6b3..88e0b793a0 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationEvaluationContextFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationEvaluationContextFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 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. @@ -79,7 +79,7 @@ public class IntegrationEvaluationContextFactoryBean extends AbstractEvaluationC } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { if (getApplicationContext() != null) { this.beanResolver = new BeanFactoryResolver(getApplicationContext()); } @@ -87,7 +87,7 @@ public class IntegrationEvaluationContextFactoryBean extends AbstractEvaluationC } @Override - public StandardEvaluationContext getObject() throws Exception { + public StandardEvaluationContext getObject() { StandardEvaluationContext evaluationContext = new StandardEvaluationContext(); if (this.typeLocator != null) { evaluationContext.setTypeLocator(this.typeLocator); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java index 70fbdff980..f931cba72c 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2018 the original author or authors. + * Copyright 2015-2019 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. @@ -272,12 +272,12 @@ public class IntegrationManagementConfigurer } @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + public Object postProcessAfterInitialization(Object bean, String name) throws BeansException { if (this.singletonsInstantiated) { if (bean instanceof IntegrationManagement) { ((IntegrationManagement) bean).registerMetricsCaptor(this.metricsCaptor); } - return doConfigureMetrics(bean, beanName); + return doConfigureMetrics(bean, name); } return bean; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationSimpleEvaluationContextFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationSimpleEvaluationContextFactoryBean.java index 67f1791d02..e13396c418 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationSimpleEvaluationContextFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationSimpleEvaluationContextFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2019 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,12 +68,12 @@ public class IntegrationSimpleEvaluationContextFactoryBean extends AbstractEvalu } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { initialize(IntegrationContextUtils.INTEGRATION_SIMPLE_EVALUATION_CONTEXT_BEAN_NAME); } @Override - public SimpleEvaluationContext getObject() throws Exception { + public SimpleEvaluationContext getObject() { Collection accessors = getPropertyAccessors().values(); PropertyAccessor[] accessorArray = accessors.toArray(new PropertyAccessor[accessors.size() + 2]); accessorArray[accessors.size()] = new MapAccessor(); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java index 74c67b38ac..14a4cac864 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -57,7 +57,7 @@ public class ReleaseStrategyFactoryBean implements FactoryBean, } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { if (this.target instanceof ReleaseStrategy && !StringUtils.hasText(this.methodName)) { this.strategy = (ReleaseStrategy) this.target; return; @@ -88,7 +88,7 @@ public class ReleaseStrategyFactoryBean implements FactoryBean, } @Override - public ReleaseStrategy getObject() throws Exception { + public ReleaseStrategy getObject() { return this.strategy; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/SourcePollingChannelAdapterFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/SourcePollingChannelAdapterFactoryBean.java index 624cfa16fd..7bb1814d4e 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/SourcePollingChannelAdapterFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/SourcePollingChannelAdapterFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -137,7 +137,7 @@ public class SourcePollingChannelAdapterFactoryBean implements FactoryBean, Initializin } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { this.method = BeanUtils.resolveSignature(this.functionMethodSignature, this.functionClass); if (this.method == null) { @@ -74,7 +74,7 @@ public class SpelFunctionFactoryBean implements FactoryBean, Initializin } @Override - public Method getObject() throws Exception { + public Method getObject() { return this.method; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/Disposables.java b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/Disposables.java index 44785428e8..2b767d26cb 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/Disposables.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/Disposables.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2019 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. @@ -36,17 +36,19 @@ class Disposables implements DisposableBean { private final List disposables = new ArrayList<>(); - public void add(DisposableBean... disposables) { - this.disposables.addAll(Arrays.asList(disposables)); + @SafeVarargs + @SuppressWarnings("varargs") + public final void add(DisposableBean... disposablesToAdd) { + this.disposables.addAll(Arrays.asList(disposablesToAdd)); } @Override - public void destroy() throws Exception { + public void destroy() { this.disposables.forEach(d -> { try { d.destroy(); } - catch (Exception e) { + catch (@SuppressWarnings("unused") Exception e) { // NOSONAR } }); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/context/ConverterRegistrar.java b/spring-integration-core/src/main/java/org/springframework/integration/context/ConverterRegistrar.java index a955854723..85ee83d9ee 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/context/ConverterRegistrar.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/context/ConverterRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -54,7 +54,7 @@ class ConverterRegistrar implements InitializingBean, BeanFactoryAware { } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { Assert.notNull(this.beanFactory, "BeanFactory is required"); ConversionService conversionService = IntegrationUtils.getConversionService(this.beanFactory); if (conversionService instanceof GenericConversionService) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java index 8ce17ff475..d232ed7390 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java @@ -112,14 +112,14 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport this.roleController.addLifecycleToRole(this.role, this); } - catch (NoSuchBeanDefinitionException e) { + catch (@SuppressWarnings("unused") NoSuchBeanDefinitionException e) { this.logger.trace("No LifecycleRoleController in the context"); } } } @Override - public void destroy() throws Exception { // NOSONAR TODO: remove throws in 5.2 + public void destroy() { if (this.roleController != null) { this.roleController.removeLifecycle(this); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java index 4f92229514..c8acd927fd 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java @@ -229,7 +229,7 @@ public abstract class AbstractMessageSource extends AbstractExpressionEvaluat protected abstract Object doReceive(); @Override - public void destroy() throws Exception { + public void destroy() { if (this.receiveCounter != null) { this.receiveCounter.remove(); } 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 d2e3ed28ac..d25915ac17 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 @@ -421,7 +421,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } @Override - public Object getObject() throws Exception { + public Object getObject() { if (this.serviceProxy == null) { this.onInit(); Assert.notNull(this.serviceProxy, "failed to initialize proxy"); @@ -436,7 +436,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint @Override @Nullable - public Object invoke(final MethodInvocation invocation) throws Throwable { + public Object invoke(final MethodInvocation invocation) throws Throwable { // NOSONAR final Class returnType = invocation.getMethod().getReturnType(); if (this.asyncExecutor != null && !Object.class.equals(returnType)) { Invoker invoker = new Invoker(invocation); @@ -479,7 +479,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } @Nullable - private Object invokeGatewayMethod(MethodInvocation invocation, boolean runningOnCallerThread) throws Exception { + private Object invokeGatewayMethod(MethodInvocation invocation, boolean runningOnCallerThread) { if (!this.initialized) { this.afterPropertiesSet(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractMessageHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractMessageHandler.java index f2268cf143..4ce9e6b120 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractMessageHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractMessageHandler.java @@ -96,8 +96,8 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport } @Override - public void registerMetricsCaptor(MetricsCaptor metricsCaptor) { - this.metricsCaptor = metricsCaptor; + public void registerMetricsCaptor(MetricsCaptor metricsCaptorToRegister) { + this.metricsCaptor = metricsCaptorToRegister; } @Override @@ -222,7 +222,7 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport } - protected abstract void handleMessageInternal(Message message) throws Exception; + protected abstract void handleMessageInternal(Message message); @Override public void reset() { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionEvaluatingMessageHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionEvaluatingMessageHandler.java index d4d5ed9865..105584b458 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionEvaluatingMessageHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionEvaluatingMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -58,7 +58,7 @@ public class ExpressionEvaluatingMessageHandler extends AbstractMessageHandler { } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { this.processor.processMessage(message); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java index 20aaef3cb0..79b161abd6 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -63,8 +63,8 @@ import org.springframework.util.Assert; * @author Gary Russell * @author Artem Bilan */ -public class MessageHandlerChain extends AbstractMessageProducingHandler implements MessageProducer, - CompositeMessageHandler, Lifecycle { +public class MessageHandlerChain extends AbstractMessageProducingHandler + implements CompositeMessageHandler, Lifecycle { private volatile List handlers; @@ -103,7 +103,7 @@ public class MessageHandlerChain extends AbstractMessageProducingHandler impleme } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { if (!this.initialized) { this.onInit(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/AbstractRequestHandlerAdvice.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/AbstractRequestHandlerAdvice.java index ff3cc4dae1..35d78048c9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/AbstractRequestHandlerAdvice.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/AbstractRequestHandlerAdvice.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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,13 +20,12 @@ import java.lang.reflect.Method; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.aop.ProxyMethodInvocation; import org.springframework.integration.context.IntegrationObjectSupport; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandler; +import org.springframework.messaging.MessagingException; /** * Base class for {@link MessageHandler} advice classes. Subclasses should provide an @@ -42,8 +41,6 @@ import org.springframework.messaging.MessageHandler; public abstract class AbstractRequestHandlerAdvice extends IntegrationObjectSupport implements MethodInterceptor { - protected final Log logger = LogFactory.getLog(this.getClass()); - @Override public final Object invoke(final MethodInvocation invocation) throws Throwable { @@ -70,20 +67,17 @@ public abstract class AbstractRequestHandlerAdvice extends IntegrationObjectSupp return doInvoke(new ExecutionCallback() { @Override - public Object execute() throws Exception { + public Object execute() { try { return invocation.proceed(); } - catch (Exception e) { //NOSONAR - catch necessary so we can wrap Errors - throw e; - } catch (Throwable e) { //NOSONAR - ok to catch; unwrapped and rethrown below throw new ThrowableHolderException(e); } } @Override - public Object cloneAndExecute() throws Exception { + public Object cloneAndExecute() { try { /* * If we don't copy the invocation carefully it won't keep a reference to the other @@ -99,7 +93,7 @@ public abstract class AbstractRequestHandlerAdvice extends IntegrationObjectSupp } } catch (Exception e) { //NOSONAR - catch necessary so we can wrap Errors - throw e; + throw new MessagingException(message, "Failed to handle", e); } catch (Throwable e) { //NOSONAR - ok to catch; unwrapped and rethrown below throw new ThrowableHolderException(e); @@ -122,9 +116,8 @@ public abstract class AbstractRequestHandlerAdvice extends IntegrationObjectSupp * @param target The target handler. * @param message The message that will be sent to the handler. * @return the result after invoking the {@link MessageHandler}. - * @throws Exception Any Exception. */ - protected abstract Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception; + protected abstract Object doInvoke(ExecutionCallback callback, Object target, Message message); /** * Unwrap the cause of a {@link AbstractRequestHandlerAdvice.ThrowableHolderException}. @@ -165,9 +158,8 @@ public abstract class AbstractRequestHandlerAdvice extends IntegrationObjectSupp * Call this for a normal invocation.proceed(). * * @return The result of the execution. - * @throws Exception Any Exception. */ - Object execute() throws Exception; + Object execute(); /** * Call this when it is necessary to clone the invocation before @@ -175,14 +167,13 @@ public abstract class AbstractRequestHandlerAdvice extends IntegrationObjectSupp * multiple times - for example in a retry advice. * * @return The result of the execution. - * @throws Exception Any Exception. */ - Object cloneAndExecute() throws Exception; + Object cloneAndExecute(); } @SuppressWarnings("serial") - private static final class ThrowableHolderException extends RuntimeException { + protected static final class ThrowableHolderException extends RuntimeException { ThrowableHolderException(Throwable cause) { super(cause); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ErrorMessageSendingRecoverer.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ErrorMessageSendingRecoverer.java index 884bd270f1..e54a341bbd 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ErrorMessageSendingRecoverer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ErrorMessageSendingRecoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -79,7 +79,7 @@ public class ErrorMessageSendingRecoverer extends ErrorMessagePublisher implemen } @Override - public Object recover(RetryContext context) throws Exception { + public Object recover(RetryContext context) { publish(context.getLastThrowable(), context); return null; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java index 5ae8ea7ef2..744cab043d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java @@ -232,9 +232,7 @@ public class ExpressionEvaluatingRequestHandlerAdvice extends AbstractRequestHan } @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) - throws Exception { // NOSONAR - + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { try { Object result = callback.execute(); if (this.onSuccessExpression != null) { @@ -242,7 +240,7 @@ public class ExpressionEvaluatingRequestHandlerAdvice extends AbstractRequestHan } return result; } - catch (Exception e) { + catch (RuntimeException e) { Exception actualException = unwrapExceptionIfNecessary(e); if (this.onFailureExpression != null) { Object evalResult = evaluateFailureExpression(message, actualException); @@ -251,13 +249,18 @@ public class ExpressionEvaluatingRequestHandlerAdvice extends AbstractRequestHan } } if (!this.trapException) { - throw actualException; + if (e instanceof ThrowableHolderException) { // NOSONAR + throw (ThrowableHolderException) e; + } + else { + throw new ThrowableHolderException(actualException); // NOSONAR lost stack trace + } } return null; } } - private void evaluateSuccessExpression(Message message) throws Exception { // NOSONAR + private void evaluateSuccessExpression(Message message) { Object evalResult; try { evalResult = this.onSuccessExpression.getValue(prepareEvaluationContextToUse(null), message); @@ -274,7 +277,7 @@ public class ExpressionEvaluatingRequestHandlerAdvice extends AbstractRequestHan this.messagingTemplate.send(this.successChannel, resultMessage); } if (evalResult instanceof Exception && this.propagateOnSuccessEvaluationFailures) { - throw (Exception) evalResult; + throw new ThrowableHolderException((Exception) evalResult); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RateLimiterRequestHandlerAdvice.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RateLimiterRequestHandlerAdvice.java index 82f38c4e28..7705041102 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RateLimiterRequestHandlerAdvice.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RateLimiterRequestHandlerAdvice.java @@ -119,7 +119,7 @@ public class RateLimiterRequestHandlerAdvice extends AbstractRequestHandlerAdvic } /** - * Get a {@link RateLimiter} which is configured for this advice. + * Get the {@link RateLimiter} which is configured for this advice. * @return the {@link RateLimiter} for this advice. */ public RateLimiter getRateLimiter() { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerCircuitBreakerAdvice.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerCircuitBreakerAdvice.java index f90e0605b8..2248422088 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerCircuitBreakerAdvice.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerCircuitBreakerAdvice.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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,7 +51,7 @@ public class RequestHandlerCircuitBreakerAdvice extends AbstractRequestHandlerAd } @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { AdvisedMetadata metadata = this.metadataMap.get(target); if (metadata == null) { this.metadataMap.putIfAbsent(target, new AdvisedMetadata()); @@ -72,7 +72,12 @@ public class RequestHandlerCircuitBreakerAdvice extends AbstractRequestHandlerAd catch (Exception e) { metadata.getFailures().incrementAndGet(); metadata.setLastFailure(System.currentTimeMillis()); - throw this.unwrapExceptionIfNecessary(e); + if (e instanceof ThrowableHolderException) { // NOSONAR + throw (ThrowableHolderException) e; + } + else { + throw new ThrowableHolderException(e); + } } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerRetryAdvice.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerRetryAdvice.java index 7d9860c33b..2ad5165481 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerRetryAdvice.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/RequestHandlerRetryAdvice.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,15 +42,20 @@ import org.springframework.util.Assert; public class RequestHandlerRetryAdvice extends AbstractRequestHandlerAdvice implements RetryListener { - private volatile RetryTemplate retryTemplate = new RetryTemplate(); + private RetryTemplate retryTemplate = new RetryTemplate(); - private volatile RecoveryCallback recoveryCallback; + private RecoveryCallback recoveryCallback; private static final ThreadLocal> messageHolder = new ThreadLocal>(); // Stateless unless a state generator is provided private volatile RetryStateGenerator retryStateGenerator = message -> null; + /** + * Set the retry template. Cause traversal should be enabled in the retry policy + * because user exceptions may be wrapped in a {@link MessagingException}. + * @param retryTemplate the retry template. + */ public void setRetryTemplate(RetryTemplate retryTemplate) { Assert.notNull(retryTemplate, "'retryTemplate' cannot be null"); this.retryTemplate = retryTemplate; @@ -72,8 +77,7 @@ public class RequestHandlerRetryAdvice extends AbstractRequestHandlerAdvice } @Override - protected Object doInvoke(final ExecutionCallback callback, Object target, final Message message) - throws Exception { + protected Object doInvoke(final ExecutionCallback callback, Object target, final Message message) { RetryState retryState = null; retryState = this.retryStateGenerator.determineRetryState(message); messageHolder.set(message); @@ -87,8 +91,11 @@ public class RequestHandlerRetryAdvice extends AbstractRequestHandlerAdvice } throw e; } + catch (ThrowableHolderException e) { // NOSONAR catch and rethrow + throw e; + } catch (Exception e) { - throw new MessagingException(message, "Failed to invoke handler", unwrapExceptionIfNecessary(e)); + throw new ThrowableHolderException(e); } finally { messageHolder.remove(); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MapArgumentResolver.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MapArgumentResolver.java index c107663ed2..8bc81130a7 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MapArgumentResolver.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MapArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 the original author or authors. + * Copyright 2017-2019 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. @@ -58,7 +58,7 @@ public class MapArgumentResolver extends AbstractExpressionEvaluator @Override @SuppressWarnings("unchecked") - public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { + public Object resolveArgument(MethodParameter parameter, Message message) { Object payload = message.getPayload(); if (Properties.class.isAssignableFrom(parameter.getParameterType())) { Map map = message.getHeaders(); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadExpressionArgumentResolver.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadExpressionArgumentResolver.java index 847e24c01f..42a2f84abd 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadExpressionArgumentResolver.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadExpressionArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,7 @@ public class PayloadExpressionArgumentResolver extends AbstractExpressionEvaluat } @Override - public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { + public Object resolveArgument(MethodParameter parameter, Message message) { Expression expression = this.expressionCache.get(parameter); if (expression == null) { Payload ann = parameter.getParameterAnnotation(Payload.class); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadsArgumentResolver.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadsArgumentResolver.java index 2276a7f17a..c058b19884 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadsArgumentResolver.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/PayloadsArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 the original author or authors. + * Copyright 2017-2019 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. @@ -55,7 +55,7 @@ public class PayloadsArgumentResolver extends AbstractExpressionEvaluator @Override @SuppressWarnings("unchecked") - public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { + public Object resolveArgument(MethodParameter parameter, Message message) { Object payload = message.getPayload(); Assert.state(payload instanceof Collection, "This Argument Resolver support only messages with payload as Collection>"); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/mapping/OutboundMessageMapper.java b/spring-integration-core/src/main/java/org/springframework/integration/mapping/OutboundMessageMapper.java index 22fa7c0f46..d03be4a3aa 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/mapping/OutboundMessageMapper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/mapping/OutboundMessageMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -29,6 +29,6 @@ import org.springframework.messaging.Message; public interface OutboundMessageMapper { @Nullable - T fromMessage(Message message) throws Exception; + T fromMessage(Message message) throws Exception; // NOSONAR } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/JavaUtils.java b/spring-integration-core/src/main/java/org/springframework/integration/util/JavaUtils.java index 2d6329dd29..8caaf75630 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/JavaUtils.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/JavaUtils.java @@ -16,8 +16,14 @@ package org.springframework.integration.util; +import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + /** * Chained utility methods to simplify some Java repetitive code. Obtain a reference to * the singleton {@link #INSTANCE} and then chain calls to the utility methods. @@ -67,4 +73,103 @@ public final class JavaUtils { return this; } + /** + * Invoke {@link Consumer#accept(Object)} with the value if it is not null or empty. + * @param value the value. + * @param consumer the consumer. + * @return this. + * @since 5.2 + */ + public JavaUtils acceptIfHasText(String value, Consumer consumer) { + if (StringUtils.hasText(value)) { + consumer.accept(value); + } + return this; + } + + /** + * Invoke {@link Consumer#accept(Object)} with the value if it is not null or empty. + * @param value the value. + * @param consumer the consumer. + * @param the value type. + * @return this. + * @since 5.2 + */ + public JavaUtils acceptIfNotEmpty(List value, Consumer> consumer) { + if (!CollectionUtils.isEmpty(value)) { + consumer.accept(value); + } + return this; + } + + /** + * Invoke {@link Consumer#accept(Object)} with the value if it is not null or empty. + * @param value the value. + * @param consumer the consumer. + * @param the value type. + * @return this. + * @since 5.2 + */ + public JavaUtils acceptIfNotEmpty(T[] value, Consumer consumer) { + if (!ObjectUtils.isEmpty(value)) { + consumer.accept(value); + } + return this; + } + + /** + * Invoke {@link BiConsumer#accept(Object, Object)} with the arguments if the + * condition is true. + * @param condition the condition. + * @param t1 the first consumer argument + * @param t2 the second consumer argument + * @param consumer the consumer. + * @param the first argument type. + * @param the second argument type. + * @return this. + * @since 5.2 + */ + public JavaUtils acceptIfCondition(boolean condition, T1 t1, T2 t2, BiConsumer consumer) { + if (condition) { + consumer.accept(t1, t2); + } + return this; + } + + /** + * Invoke {@link BiConsumer#accept(Object, Object)} with the arguments if the t2 + * argument is not null. + * @param t1 the first argument + * @param t2 the second consumer argument + * @param consumer the consumer. + * @param the first argument type. + * @param the second argument type. + * @return this. + * @since 5.2 + */ + public JavaUtils acceptIfNotNull(T1 t1, T2 t2, BiConsumer consumer) { + if (t2 != null) { + consumer.accept(t1, t2); + } + return this; + } + + /** + * Invoke {@link BiConsumer#accept(Object, Object)} with the arguments if the value + * argument is not null or empty. + * @param t1 the first consumer argument. + * @param value the second consumer argument + * @param the first argument type. + * @param consumer the consumer. + * @return this. + * @since 5.2 + */ + public JavaUtils acceptIfHasText(T t1, String value, BiConsumer consumer) { + if (StringUtils.hasText(value)) { + consumer.accept(t1, value); + } + return this; + } + + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests.java index 096751ad41..d7124b604b 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests.java @@ -190,7 +190,7 @@ public class FilterParserTests { public static class FooFilter extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/FilterAnnotationPostProcessorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/FilterAnnotationPostProcessorTests.java index 86b69371a0..df6a52fc9a 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/FilterAnnotationPostProcessorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/FilterAnnotationPostProcessorTests.java @@ -273,7 +273,7 @@ public class FilterAnnotationPostProcessorTests { public static class TestAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { return callback.execute(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java index 61bdbaf8dc..bcf33eeee2 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java @@ -395,7 +395,7 @@ public class MessagingAnnotationPostProcessorTests { public static class ServiceActivatorAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { return callback.execute() + " advised"; } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java index 34837214d9..8697f97974 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests.java @@ -258,7 +258,7 @@ public class EnricherParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests4.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests4.java index df94526855..ac6f0aeb9d 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests4.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/EnricherParserTests4.java @@ -146,7 +146,7 @@ public class EnricherParserTests4 { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ServiceActivatorParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ServiceActivatorParserTests.java index 1d51f43d28..51971b9539 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ServiceActivatorParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ServiceActivatorParserTests.java @@ -279,7 +279,7 @@ public class ServiceActivatorParserTests { public static class BarAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { callback.execute(); return "bar"; } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dsl/transformers/TransformerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/dsl/transformers/TransformerTests.java index 217f56d935..9af4523f15 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/dsl/transformers/TransformerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/dsl/transformers/TransformerTests.java @@ -375,9 +375,7 @@ public class TransformerTests { return new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) - throws Exception { - + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceChannel().send(message); return callback.execute(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java index 0546ab82d6..9ecbe237e3 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java @@ -146,7 +146,7 @@ public class AdvisedMessageHandlerTests { adviceChain.add(new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { compName.set(((AbstractReplyProducingMessageHandler.RequestHandler) target).getAdvisedHandler() .getComponentName()); return callback.execute(); @@ -734,7 +734,7 @@ public class AdvisedMessageHandlerTests { adviceChain.add(new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { outerCounter.incrementAndGet(); return callback.execute(); } @@ -814,14 +814,18 @@ public class AdvisedMessageHandlerTests { AbstractRequestHandlerAdvice advice = new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { Object result; try { result = callback.execute(); } catch (Exception e) { - // should not be unwrapped because the cause is a Throwable - throw this.unwrapExceptionIfNecessary(e); + if (e instanceof ThrowableHolderException) { + throw (ThrowableHolderException) e; + } + else { + throw new ThrowableHolderException(e); + } } return result; } @@ -882,7 +886,7 @@ public class AdvisedMessageHandlerTests { Advice advice = new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { called.set(true); return callback.execute(); } @@ -938,7 +942,7 @@ public class AdvisedMessageHandlerTests { adviceChain.add(new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { Object result = callback.execute(); discardedWithinAdvice.set(discardChannel.receive(0)); return result; @@ -963,7 +967,7 @@ public class AdvisedMessageHandlerTests { adviceChain.add(new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { Object result = callback.execute(); discardedWithinAdvice.set(discardChannel.receive(0)); adviceCalled.set(true); @@ -1015,9 +1019,8 @@ public class AdvisedMessageHandlerTests { Map, Boolean> retryableExceptions = new HashMap, Boolean>(); retryableExceptions.put(MyException.class, retryForMyException); - retryableExceptions.put(MessagingException.class, true); - retryTemplate.setRetryPolicy(new SimpleRetryPolicy(3, retryableExceptions)); + retryTemplate.setRetryPolicy(new SimpleRetryPolicy(3, retryableExceptions, true)); advice.setRetryTemplate(retryTemplate); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/IdempotentReceiverTests.java b/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/IdempotentReceiverTests.java index 56bbcf8a62..7e1f8d7081 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/IdempotentReceiverTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/IdempotentReceiverTests.java @@ -161,7 +161,7 @@ public class IdempotentReceiverTests { private int adviceCalled; @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/TransformerContextTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/TransformerContextTests.java index c02f19f9ba..f9bad4d9de 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/TransformerContextTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/TransformerContextTests.java @@ -96,7 +96,7 @@ public class TransformerContextTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventOutboundChannelAdapterParserTests.java b/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventOutboundChannelAdapterParserTests.java index 23dc9ee8c2..45bd529447 100644 --- a/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventOutboundChannelAdapterParserTests.java +++ b/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventOutboundChannelAdapterParserTests.java @@ -161,7 +161,7 @@ public class EventOutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java index 6bdd90f9db..f854acf02e 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java @@ -204,7 +204,7 @@ public class FileTailInboundChannelAdapterFactoryBean extends AbstractFactoryBea } @Override - protected FileTailingMessageProducerSupport createInstance() throws Exception { + protected FileTailingMessageProducerSupport createInstance() { FileTailingMessageProducerSupport adapter; if (this.delay == null && this.end == null && this.reopen == null) { adapter = new OSDelegatingFileTailingMessageProducer(); diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/AbstractFilePayloadTransformer.java b/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/AbstractFilePayloadTransformer.java index 65289ab6f8..780f8aefe3 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/AbstractFilePayloadTransformer.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/AbstractFilePayloadTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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.integration.file.transformer; import java.io.File; +import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -107,8 +108,8 @@ public abstract class AbstractFilePayloadTransformer implements Transformer, * * @param file The file. * @return The result of the transformation. - * @throws Exception Any Exception. + * @throws IOException Any IOException. */ - protected abstract T transformFile(File file) throws Exception; + protected abstract T transformFile(File file) throws IOException; } diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToByteArrayTransformer.java b/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToByteArrayTransformer.java index 76ccbc22c0..a0c693bb06 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToByteArrayTransformer.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToByteArrayTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2019 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.integration.file.transformer; import java.io.File; +import java.io.IOException; import org.springframework.util.FileCopyUtils; @@ -28,7 +29,7 @@ import org.springframework.util.FileCopyUtils; public class FileToByteArrayTransformer extends AbstractFilePayloadTransformer { @Override - protected final byte[] transformFile(File file) throws Exception { + protected final byte[] transformFile(File file) throws IOException { return FileCopyUtils.copyToByteArray(file); } diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToStringTransformer.java b/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToStringTransformer.java index 9caed42133..d273295f3f 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToStringTransformer.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/transformer/FileToStringTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2019 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.file.transformer; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.Charset; @@ -49,7 +50,7 @@ public class FileToStringTransformer extends AbstractFilePayloadTransformer message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundChannelAdapterParserTests.java b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundChannelAdapterParserTests.java index 3856188b59..b690ffc72d 100644 --- a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundChannelAdapterParserTests.java +++ b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundChannelAdapterParserTests.java @@ -173,7 +173,7 @@ public class FtpOutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests.java b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests.java index 1f7bf1380f..38964e77bc 100644 --- a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests.java +++ b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests.java @@ -183,7 +183,7 @@ public class FtpOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/config/xml/GemfireOutboundChannelAdapterParserTests.java b/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/config/xml/GemfireOutboundChannelAdapterParserTests.java index 0ae3fd0984..13205f1b66 100644 --- a/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/config/xml/GemfireOutboundChannelAdapterParserTests.java +++ b/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/config/xml/GemfireOutboundChannelAdapterParserTests.java @@ -50,7 +50,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @DirtiesContext public class GemfireOutboundChannelAdapterParserTests { - private GemfireOutboundChannelAdapterParser underTest = new GemfireOutboundChannelAdapterParser(); + private final GemfireOutboundChannelAdapterParser underTest = new GemfireOutboundChannelAdapterParser(); private static final CountDownLatch adviceCalled = new CountDownLatch(1); @@ -89,7 +89,7 @@ public class GemfireOutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled.countDown(); return null; } diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyControlBusTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyControlBusTests.java index b05b1d00ae..49c62074e3 100644 --- a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyControlBusTests.java +++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyControlBusTests.java @@ -196,6 +196,7 @@ public class GroovyControlBusTests { private volatile boolean executed; + @Override public void customize(GroovyObject goo) { this.executed = true; } @@ -206,33 +207,41 @@ public class GroovyControlBusTests { private final Map fakeRequest = new HashMap<>(); + @Override public Object getAttribute(String name, int scope) { return fakeRequest.get(name); } + @Override public void setAttribute(String name, Object value, int scope) { fakeRequest.put(name, value); } + @Override public void removeAttribute(String name, int scope) { } + @Override public String[] getAttributeNames(int scope) { return null; } + @Override public void registerDestructionCallback(String name, Runnable callback, int scope) { } + @Override public Object resolveReference(String key) { return null; } + @Override public String getSessionId() { return null; } + @Override public Object getSessionMutex() { return null; } @@ -242,7 +251,7 @@ public class GroovyControlBusTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/support/DefaultHttpHeaderMapper.java b/spring-integration-http/src/main/java/org/springframework/integration/http/support/DefaultHttpHeaderMapper.java index d7a0f4b009..c880a87c49 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/support/DefaultHttpHeaderMapper.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/support/DefaultHttpHeaderMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -73,6 +73,8 @@ import org.springframework.util.StringUtils; */ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanFactoryAware, InitializingBean { + private static final String UNUSED = "unused"; + protected final Log logger = LogFactory.getLog(getClass()); public static final String ACCEPT = "Accept"; @@ -486,7 +488,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanF } @Override - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { if (this.beanFactory != null) { this.conversionService = IntegrationUtils.getConversionService(this.beanFactory); } @@ -763,7 +765,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanF try { target.setDate(Long.parseLong((String) value)); } - catch (NumberFormatException e) { + catch (@SuppressWarnings(UNUSED) NumberFormatException e) { target.setDate(this.getFirstDate((String) value, DATE)); } } @@ -794,7 +796,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanF try { target.setExpires(Long.parseLong((String) value)); } - catch (NumberFormatException e) { + catch (@SuppressWarnings(UNUSED) NumberFormatException e) { target.setExpires(this.getFirstDate((String) value, EXPIRES)); } } @@ -815,7 +817,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanF try { target.setIfModifiedSince(Long.parseLong((String) value)); } - catch (NumberFormatException e) { + catch (@SuppressWarnings(UNUSED) NumberFormatException e) { target.setIfModifiedSince(this.getFirstDate((String) value, IF_MODIFIED_SINCE)); } } @@ -838,7 +840,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanF try { ifUnmodifiedSinceValue = this.formatDate(Long.parseLong((String) value)); } - catch (NumberFormatException e) { + catch (@SuppressWarnings(UNUSED) NumberFormatException e) { long longValue = this.getFirstDate((String) value, IF_UNMODIFIED_SINCE); ifUnmodifiedSinceValue = this.formatDate(longValue); } @@ -888,7 +890,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanF try { target.setLastModified(Long.parseLong((String) value)); } - catch (NumberFormatException e) { + catch (@SuppressWarnings(UNUSED) NumberFormatException e) { target.setLastModified(this.getFirstDate((String) value, LAST_MODIFIED)); } } @@ -1078,7 +1080,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper, BeanF .toInstant() .toEpochMilli(); } - catch (DateTimeParseException ex) { + catch (@SuppressWarnings(UNUSED) DateTimeParseException ex) { // ignore } } diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java index a47d21c138..e4e186f454 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java @@ -303,7 +303,7 @@ public class HttpOutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java index 6c761d9480..e8798560ab 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java @@ -237,7 +237,7 @@ public class HttpOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/config/TcpConnectionFactoryFactoryBean.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/config/TcpConnectionFactoryFactoryBean.java index 07d2aba916..063a4d80b1 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/config/TcpConnectionFactoryFactoryBean.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/config/TcpConnectionFactoryFactoryBean.java @@ -19,7 +19,6 @@ package org.springframework.integration.ip.config; import java.util.concurrent.Executor; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.ApplicationEventPublisher; @@ -58,7 +57,7 @@ import org.springframework.util.Assert; * @since 2.0.5 */ public class TcpConnectionFactoryFactoryBean extends AbstractFactoryBean - implements Lifecycle, BeanNameAware, BeanFactoryAware, ApplicationEventPublisherAware { + implements Lifecycle, BeanNameAware, ApplicationEventPublisherAware { private volatile AbstractConnectionFactory connectionFactory; @@ -151,7 +150,7 @@ public class TcpConnectionFactoryFactoryBean extends AbstractFactoryBean replyMessage = reply.getReply(); - if (replyMessage == null) { - if (logger.isDebugEnabled()) { - logger.debug("Remote Timeout on " + connectionId); - } - // The connection is dirty - force it closed. - this.connectionFactory.forceClose(connection); - throw new MessageTimeoutException(requestMessage, "Timed out waiting for response"); - } - if (logger.isDebugEnabled()) { - logger.debug("Response " + replyMessage); - } - return replyMessage; + return getReply(requestMessage, connection, connectionId, reply); } - catch (Exception e) { + catch (RuntimeException e) { logger.error("Tcp Gateway exception", e); if (e instanceof MessagingException) { throw (MessagingException) e; } throw new MessagingException("Failed to send or receive", e); } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new MessageHandlingException(requestMessage, "Interrupted", e); + } finally { - if (connectionId != null) { - this.pendingReplies.remove(connectionId); - if (logger.isDebugEnabled()) { - logger.debug("Removed pending reply " + connectionId); - } - if (this.isSingleUse) { - connection.close(); - } + cleanUp(haveSemaphore, connection, connectionId); + } + } + + private boolean acquireSemaphoreIfNeeded(Message requestMessage) throws InterruptedException { + if (!this.isSingleUse) { + logger.debug("trying semaphore"); + if (!this.semaphore.tryAcquire(this.requestTimeout, TimeUnit.MILLISECONDS)) { + throw new MessageTimeoutException(requestMessage, "Timed out waiting for connection"); } - if (haveSemaphore) { - this.semaphore.release(); - if (logger.isDebugEnabled()) { - logger.debug("released semaphore"); - } + if (logger.isDebugEnabled()) { + logger.debug("got semaphore"); + } + return true; + } + return false; + } + + private Long getRemoteTimeout(Message requestMessage) { + Long remoteTimeout = this.remoteTimeoutExpression.getValue(this.evaluationContext, requestMessage, + Long.class); + if (remoteTimeout == null) { + remoteTimeout = DEFAULT_REMOTE_TIMEOUT; + if (logger.isWarnEnabled()) { + logger.warn("remoteTimeoutExpression evaluated to null; falling back to default for message " + + requestMessage); + } + } + return remoteTimeout; + } + + private Message getReply(Message requestMessage, TcpConnection connection, String connectionId, + AsyncReply reply) { + + Message replyMessage = reply.getReply(); + if (replyMessage == null) { + if (logger.isDebugEnabled()) { + logger.debug("Remote Timeout on " + connectionId); + } + // The connection is dirty - force it closed. + this.connectionFactory.forceClose(connection); + throw new MessageTimeoutException(requestMessage, "Timed out waiting for response"); + } + if (logger.isDebugEnabled()) { + logger.debug("Response " + replyMessage); + } + return replyMessage; + } + + private void cleanUp(boolean haveSemaphore, TcpConnection connection, String connectionId) { + if (connectionId != null) { + this.pendingReplies.remove(connectionId); + if (logger.isDebugEnabled()) { + logger.debug("Removed pending reply " + connectionId); + } + if (this.isSingleUse) { + connection.close(); + } + } + if (haveSemaphore) { + this.semaphore.release(); + if (logger.isDebugEnabled()) { + logger.debug("released semaphore"); } } } @@ -334,13 +359,13 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler * @return The return message or null if we time out * @throws Exception */ - public Message getReply() throws Exception { + public Message getReply() { try { if (!this.latch.await(this.remoteTimeout, TimeUnit.MILLISECONDS)) { return null; } } - catch (InterruptedException e) { + catch (@SuppressWarnings("unused") InterruptedException e) { Thread.currentThread().interrupt(); } boolean waitForMessageAfterError = true; @@ -351,19 +376,31 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler * before the reply, on a different thread. */ logger.debug("second chance"); - this.secondChanceLatch.await(TcpOutboundGateway.this.secondChanceDelay, TimeUnit.SECONDS); // NOSONAR + try { + this.secondChanceLatch.await(TcpOutboundGateway.this.secondChanceDelay, TimeUnit.SECONDS); // NOSONAR + } + catch (@SuppressWarnings("unused") InterruptedException e) { + Thread.currentThread().interrupt(); + doThrowErrorMessagePayload(); + } waitForMessageAfterError = false; } - else if (this.reply.getPayload() instanceof MessagingException) { - throw (MessagingException) this.reply.getPayload(); - } else { - throw new MessagingException("Exception while awaiting reply", (Throwable) this.reply.getPayload()); + doThrowErrorMessagePayload(); } } return this.reply; } + private void doThrowErrorMessagePayload() { + if (this.reply.getPayload() instanceof MessagingException) { + throw (MessagingException) this.reply.getPayload(); + } + else { + throw new MessagingException("Exception while awaiting reply", (Throwable) this.reply.getPayload()); + } + } + /** * We have a race condition when a socket is closed right after the reply is received. The close "error" * might arrive before the actual reply. Overwrite an error with a good reply, but not vice-versa. diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractClientConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractClientConnectionFactory.java index 3910561ae3..1b94b14c4b 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractClientConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractClientConnectionFactory.java @@ -63,14 +63,15 @@ public abstract class AbstractClientConnectionFactory extends AbstractConnection * Obtains a connection - if {@link #setSingleUse(boolean)} was called with * true, a new connection is returned; otherwise a single connection is * reused for all requests while the connection remains open. + * @throws InterruptedException if interrupted. */ @Override - public TcpConnectionSupport getConnection() throws Exception { - this.checkActive(); + public TcpConnectionSupport getConnection() throws InterruptedException { + checkActive(); return obtainConnection(); } - protected TcpConnectionSupport obtainConnection() throws Exception { + protected TcpConnectionSupport obtainConnection() throws InterruptedException { if (!this.isSingleUse()) { TcpConnectionSupport connection = obtainSharedConnection(); if (connection != null) { @@ -92,11 +93,10 @@ public abstract class AbstractClientConnectionFactory extends AbstractConnection finally { this.theConnectionLock.readLock().unlock(); } - return null; } - protected final TcpConnectionSupport obtainNewConnection() throws Exception { + protected final TcpConnectionSupport obtainNewConnection() throws InterruptedException { boolean singleUse = this.isSingleUse(); if (!singleUse) { this.theConnectionLock.writeLock().lockInterruptibly(); @@ -115,14 +115,14 @@ public abstract class AbstractClientConnectionFactory extends AbstractConnection logger.debug("Opening new socket connection to " + this.getHost() + ":" + this.getPort()); } - connection = this.buildNewConnection(); + connection = buildNewConnection(); if (!singleUse) { this.setTheConnection(connection); } connection.publishConnectionOpenEvent(); return connection; } - catch (Exception e) { + catch (RuntimeException e) { ApplicationEventPublisher applicationEventPublisher = getApplicationEventPublisher(); if (applicationEventPublisher != null) { applicationEventPublisher.publishEvent(new TcpConnectionFailedEvent(this, e)); @@ -136,7 +136,7 @@ public abstract class AbstractClientConnectionFactory extends AbstractConnection } } - protected TcpConnectionSupport buildNewConnection() throws Exception { + protected TcpConnectionSupport buildNewConnection() { throw new UnsupportedOperationException("Factories that don't override this class' obtainConnection() must implement this method"); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractConnectionFactory.java index cb51276b39..c60c40b430 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractConnectionFactory.java @@ -18,6 +18,7 @@ package org.springframework.integration.ip.tcp.connection; import java.io.EOFException; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; @@ -62,6 +63,8 @@ import org.springframework.util.Assert; public abstract class AbstractConnectionFactory extends IntegrationObjectSupport implements ConnectionFactory, ApplicationEventPublisherAware { + private static final String UNUSED = "unused"; + protected static final int DEFAULT_REPLY_TIMEOUT = 10000; private static final int DEFAULT_NIO_HARVEST_INTERVAL = 2000; @@ -351,24 +354,24 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport /** * Registers a TcpListener to receive messages after * the payload has been converted from the input data. - * @param listener the TcpListener. + * @param listenerToRegister the TcpListener. */ - public void registerListener(TcpListener listener) { + public void registerListener(TcpListener listenerToRegister) { Assert.isNull(this.listener, this.getClass().getName() + " may only be used by one inbound adapter"); - this.listener = listener; + this.listener = listenerToRegister; } /** * Registers a TcpSender; for server sockets, used to * provide connection information so a sender can be used * to reply to incoming messages. - * @param sender The sender + * @param senderToRegister The sender */ - public void registerSender(TcpSender sender) { + public void registerSender(TcpSender senderToRegister) { Assert.isNull(this.sender, this.getClass().getName() + " may only be used by one outbound adapter"); - this.sender = sender; + this.sender = senderToRegister; } /** @@ -557,7 +560,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport } } } - catch (InterruptedException e) { + catch (@SuppressWarnings(UNUSED) InterruptedException e) { executorService.shutdownNow(); Thread.currentThread().interrupt(); } @@ -572,7 +575,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport } } - protected TcpConnectionSupport wrapConnection(TcpConnectionSupport connectionArg) throws Exception { + protected TcpConnectionSupport wrapConnection(TcpConnectionSupport connectionArg) { TcpConnectionSupport connection = connectionArg; try { if (this.interceptorFactoryChain == null) { @@ -611,12 +614,11 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport * @param selectionCount Number of IO Events, if 0 we were probably woken up by a close. * @param selector The selector. * @param server The server socket channel. - * @param connections Map of connections. - * @throws IOException Any IOException. + * @param connectionMap Map of connections. */ protected void processNioSelections(int selectionCount, final Selector selector, @Nullable ServerSocketChannel server, - Map connections) throws IOException { + Map connectionMap) { final long now = System.currentTimeMillis(); rescheduleDelayedReads(selector, now); @@ -624,7 +626,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport now >= this.nextCheckForClosedNioConnections || selectionCount == 0) { this.nextCheckForClosedNioConnections = now + this.nioHarvestInterval; - Iterator> it = connections.entrySet().iterator(); + Iterator> it = connectionMap.entrySet().iterator(); while (it.hasNext()) { SocketChannel channel = it.next().getKey(); if (!channel.isOpen()) { @@ -632,7 +634,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport it.remove(); } else if (this.soTimeout > 0) { - TcpNioConnection connection = connections.get(channel); + TcpNioConnection connection = connectionMap.get(channel); if (now - connection.getLastRead() >= this.soTimeout) { /* * For client connections, we have to wait for 2 timeouts if the last @@ -650,7 +652,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport if (logger.isWarnEnabled()) { logger.warn("Timing out TcpNioConnection " + connection.getConnectionId()); } - SocketTimeoutException exception = new SocketTimeoutException("Timing out connection"); + Exception exception = new SocketTimeoutException("Timing out connection"); connection.publishConnectionExceptionEvent(exception); connection.timeout(); connection.sendExceptionToListener(exception); @@ -689,7 +691,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport try { connection.readPacket(); } - catch (RejectedExecutionException e1) { + catch (@SuppressWarnings(UNUSED) RejectedExecutionException e1) { delayRead(selector, now, key); delayed = true; } @@ -715,7 +717,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport } }); } - catch (RejectedExecutionException e) { + catch (@SuppressWarnings(UNUSED) RejectedExecutionException e) { delayRead(selector, now, key); } } @@ -731,7 +733,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport logger.error("Unexpected key: " + key); } } - catch (CancelledKeyException e) { + catch (@SuppressWarnings(UNUSED) CancelledKeyException e) { if (logger.isDebugEnabled()) { logger.debug("Selection key " + key + " cancelled"); } @@ -787,7 +789,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport } } } - catch (InterruptedException e) { + catch (@SuppressWarnings(UNUSED) InterruptedException e) { Thread.currentThread().interrupt(); } finally { @@ -801,9 +803,8 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport * @param selector The selector. * @param server The server socket channel. * @param now The current time. - * @throws IOException Any IOException. */ - protected void doAccept(final Selector selector, ServerSocketChannel server, long now) throws IOException { + protected void doAccept(final Selector selector, ServerSocketChannel server, long now) { throw new UnsupportedOperationException("Nio server factory must override this method"); } @@ -874,9 +875,9 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport this.active = active; } - protected void checkActive() throws IOException { + protected void checkActive() { if (!this.isActive()) { - throw new IOException(this + " connection factory has not been started"); + throw new UncheckedIOException(new IOException(this + " connection factory has not been started")); } } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractServerConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractServerConnectionFactory.java index c7a0aa1f11..64dd5f68a6 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractServerConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractServerConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2018 the original author or authors. + * Copyright 2001-2019 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. @@ -214,7 +214,7 @@ public abstract class AbstractServerConnectionFactory extends AbstractConnection try { taskScheduler.schedule((Runnable) () -> eventPublisher.publishEvent(event), new Date()); } - catch (TaskRejectedException e) { + catch (@SuppressWarnings("unused") TaskRejectedException e) { eventPublisher.publishEvent(event); } } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactory.java index e30dbe6bba..959e028bf5 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -133,7 +133,7 @@ public class CachingClientConnectionFactory extends AbstractClientConnectionFact } @Override - public TcpConnectionSupport obtainConnection() throws Exception { + public TcpConnectionSupport obtainConnection() { return new CachedConnection(this.pool.getItem(), getListener()); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNetConnectionSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNetConnectionSupport.java index 64aca87f72..0f12c884d9 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNetConnectionSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNetConnectionSupport.java @@ -34,7 +34,7 @@ public class DefaultTcpNetConnectionSupport extends AbstractTcpConnectionSupport @Override public TcpNetConnection createNewConnection(Socket socket, boolean server, boolean lookupHost, - ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) throws Exception { + ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) { if (isPushbackCapable()) { return new PushBackTcpNetConnection(socket, server, lookupHost, applicationEventPublisher, connectionFactoryName, getPushbackBufferSize()); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioConnectionSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioConnectionSupport.java index 421653faa1..17c8eb062f 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioConnectionSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioConnectionSupport.java @@ -38,7 +38,7 @@ public class DefaultTcpNioConnectionSupport extends AbstractTcpConnectionSupport @Override public TcpNioConnection createNewConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, - ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) throws Exception { + ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) { if (isPushbackCapable()) { return new PushBackTcpNioConnection(socketChannel, server, lookupHost, applicationEventPublisher, connectionFactoryName, getPushbackBufferSize()); @@ -61,7 +61,7 @@ public class DefaultTcpNioConnectionSupport extends AbstractTcpConnectionSupport PushBackTcpNioConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, ApplicationEventPublisher applicationEventPublisher, @Nullable String connectionFactoryName, - int bufferSize) throws Exception { + int bufferSize) { super(socketChannel, server, lookupHost, applicationEventPublisher, connectionFactoryName); this.pushbackBufferSize = bufferSize; diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java index 64477f67e4..0ea2e91763 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java @@ -75,7 +75,7 @@ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupp */ @Override public TcpNioConnection createNewConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, - ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) throws Exception { + ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) { SSLEngine sslEngine = this.sslContext.createSSLEngine(); postProcessSSLEngine(sslEngine); @@ -120,7 +120,8 @@ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupp PushBackTcpNioSSLConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName, SSLEngine sslEngine, - int bufferSize) throws Exception { + int bufferSize) { + super(socketChannel, server, lookupHost, applicationEventPublisher, connectionFactoryName, sslEngine); this.pushbackBufferSize = bufferSize; this.connectionId = "pushback:" + super.getConnectionId(); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactory.java index 24afeac35f..314b0db91a 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -92,7 +92,7 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac } @Override - protected TcpConnectionSupport obtainConnection() throws Exception { + protected TcpConnectionSupport obtainConnection() throws InterruptedException { TcpConnectionSupport connection = this.getTheConnection(); if (connection != null && connection.isOpen()) { ((FailoverTcpConnection) connection).incrementEpoch(); @@ -146,7 +146,7 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac */ private final class FailoverTcpConnection extends TcpConnectionSupport implements TcpListener { - private final List factories; + private final List connectionFactories; private final String connectionId; @@ -160,8 +160,8 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac private final AtomicLong epoch = new AtomicLong(); - private FailoverTcpConnection(List factories) throws Exception { - this.factories = factories; + private FailoverTcpConnection(List factories) throws InterruptedException { + this.connectionFactories = factories; this.factoryIterator = factories.iterator(); findAConnection(); this.connectionId = UUID.randomUUID().toString(); @@ -177,14 +177,14 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac * This allows for the condition where the current connection is closed, * the current factory can serve up a new connection, but all other * factories are down. - * @throws Exception if an exception occurs + * @throws InterruptedException if interrupted. */ - private synchronized void findAConnection() throws Exception { + private synchronized void findAConnection() throws InterruptedException { boolean success = false; AbstractClientConnectionFactory lastFactoryToTry = this.currentFactory; AbstractClientConnectionFactory nextFactory = null; if (!this.factoryIterator.hasNext()) { - this.factoryIterator = this.factories.iterator(); + this.factoryIterator = this.connectionFactories.iterator(); } boolean retried = false; while (!success) { @@ -198,7 +198,7 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac this.currentFactory = nextFactory; success = this.delegate.isOpen(); } - catch (Exception e) { + catch (RuntimeException e) { if (logger.isDebugEnabled()) { logger.debug(nextFactory + " failed with " + e.toString() @@ -213,7 +213,7 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac this.open = false; throw e; } - this.factoryIterator = this.factories.iterator(); + this.factoryIterator = this.connectionFactories.iterator(); retried = true; } } @@ -237,7 +237,7 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac * If send fails on a connection from every factory, we give up. */ @Override - public synchronized void send(Message message) throws Exception { + public synchronized void send(Message message) { boolean success = false; AbstractClientConnectionFactory lastFactoryToTry = this.currentFactory; AbstractClientConnectionFactory lastFactoryTried = null; @@ -248,7 +248,7 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac this.delegate.send(message); success = true; } - catch (Exception e) { + catch (RuntimeException e) { if (retried && lastFactoryTried == lastFactoryToTry) { logger.error("All connection factories exhausted", e); this.open = false; @@ -259,7 +259,12 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac logger.debug("Send to " + this.delegate.getConnectionId() + " failed; attempting failover", e); } this.delegate.close(); - findAConnection(); + try { + findAConnection(); + } + catch (@SuppressWarnings("unused") InterruptedException e1) { + Thread.currentThread().interrupt(); + } if (logger.isDebugEnabled()) { logger.debug("Failing over to " + this.delegate.getConnectionId()); } @@ -268,7 +273,7 @@ public class FailoverClientConnectionFactory extends AbstractClientConnectionFac } @Override - public Object getPayload() throws Exception { + public Object getPayload() { return this.delegate.getPayload(); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnection.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnection.java index e573d4ad99..fae2e7c590 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnection.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2018 the original author or authors. + * Copyright 2001-2019 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. @@ -47,18 +47,16 @@ public interface TcpConnection extends Runnable { /** * Converts and sends the message. * @param message The message, - * @throws Exception Any Exception. */ - void send(Message message) throws Exception; + void send(Message message); /** * Uses the deserializer to obtain the message payload * from the connection's input stream. * @return The payload. - * @throws Exception Any Exception. */ @Nullable - Object getPayload() throws Exception; + Object getPayload(); /** * @return the host name diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnectionInterceptorSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnectionInterceptorSupport.java index 9a94c4aed0..0285880bd7 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnectionInterceptorSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpConnectionInterceptorSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -60,7 +60,7 @@ public abstract class TcpConnectionInterceptorSupport extends TcpConnectionSuppo } @Override - public Object getPayload() throws Exception { + public Object getPayload() { return this.theConnection.getPayload(); } @@ -165,7 +165,7 @@ public abstract class TcpConnectionInterceptorSupport extends TcpConnectionSuppo } @Override - public void send(Message message) throws Exception { + public void send(Message message) { this.theConnection.send(message); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetClientConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetClientConnectionFactory.java index 097ead06fe..fb62a8811e 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetClientConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetClientConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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,8 +17,8 @@ package org.springframework.integration.ip.tcp.connection; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.Socket; -import java.net.SocketException; import org.springframework.util.Assert; @@ -45,16 +45,21 @@ public class TcpNetClientConnectionFactory extends } @Override - protected TcpConnectionSupport buildNewConnection() throws IOException, SocketException, Exception { - Socket socket = createSocket(this.getHost(), this.getPort()); - setSocketAttributes(socket); - TcpConnectionSupport connection = this.tcpNetConnectionSupport.createNewConnection(socket, false, isLookupHost(), - getApplicationEventPublisher(), getComponentName()); - connection = wrapConnection(connection); - initializeConnection(connection, socket); - this.getTaskExecutor().execute(connection); - this.harvestClosedConnections(); - return connection; + protected TcpConnectionSupport buildNewConnection() { + try { + Socket socket = createSocket(this.getHost(), this.getPort()); + setSocketAttributes(socket); + TcpConnectionSupport connection = this.tcpNetConnectionSupport.createNewConnection(socket, false, isLookupHost(), + getApplicationEventPublisher(), getComponentName()); + connection = wrapConnection(connection); + initializeConnection(connection, socket); + this.getTaskExecutor().execute(connection); + this.harvestClosedConnections(); + return connection; + } + catch (IOException e) { + throw new UncheckedIOException(e); + } } /** diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnection.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnection.java index d9daccf87d..8ef624ef28 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnection.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnection.java @@ -20,9 +20,11 @@ import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; +import java.util.function.Supplier; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; @@ -85,7 +87,7 @@ public class TcpNetConnection extends TcpConnectionSupport implements Scheduling try { this.socket.close(); } - catch (Exception e) { + catch (@SuppressWarnings("unused") Exception e) { } super.close(); } @@ -97,23 +99,24 @@ public class TcpNetConnection extends TcpConnectionSupport implements Scheduling @Override @SuppressWarnings("unchecked") - public synchronized void send(Message message) throws Exception { - if (this.socketOutputStream == null) { - int writeBufferSize = this.socket.getSendBufferSize(); - this.socketOutputStream = new BufferedOutputStream(this.socket.getOutputStream(), - writeBufferSize > 0 ? writeBufferSize : 8192); - } - Object object = getMapper().fromMessage(message); - Assert.state(object != null, "Mapper mapped the message to 'null'."); - this.lastSend = System.currentTimeMillis(); + public synchronized void send(Message message) { try { + if (this.socketOutputStream == null) { + int writeBufferSize = this.socket.getSendBufferSize(); + this.socketOutputStream = new BufferedOutputStream(this.socket.getOutputStream(), + writeBufferSize > 0 ? writeBufferSize : 8192); + } + Object object = getMapper().fromMessage(message); + Assert.state(object != null, "Mapper mapped the message to 'null'."); + this.lastSend = System.currentTimeMillis(); ((Serializer) getSerializer()).serialize(object, this.socketOutputStream); this.socketOutputStream.flush(); } catch (Exception e) { - publishConnectionExceptionEvent(new MessagingException(message, "Failed TCP serialization", e)); + MessagingException mex = new MessagingException(message, "Send Failed", e); + publishConnectionExceptionEvent(mex); closeConnection(true); - throw e; + throw mex; } if (logger.isDebugEnabled()) { logger.debug(getConnectionId() + " Message sent " + message); @@ -121,9 +124,14 @@ public class TcpNetConnection extends TcpConnectionSupport implements Scheduling } @Override - public Object getPayload() throws Exception { - return getDeserializer() - .deserialize(inputStream()); + public Object getPayload() { + try { + return getDeserializer() + .deserialize(inputStream()); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } } @Override @@ -137,7 +145,7 @@ public class TcpNetConnection extends TcpConnectionSupport implements Scheduling try { return inputStream(); } - catch (Exception e) { + catch (@SuppressWarnings("unused") Exception e) { return null; } } @@ -198,7 +206,7 @@ public class TcpNetConnection extends TcpConnectionSupport implements Scheduling } listener.onMessage(message); } - catch (NoListenerException nle) { // could also be thrown by an interceptor + catch (@SuppressWarnings("unused") NoListenerException nle) { // could also be thrown by an interceptor if (logger.isWarnEnabled()) { logger.warn("Unexpected message - no endpoint registered with connection interceptor: " + getConnectionId() @@ -213,12 +221,33 @@ public class TcpNetConnection extends TcpConnectionSupport implements Scheduling } } - protected boolean handleReadException(Exception e) { + protected boolean handleReadException(Exception exception) { + Exception e = exception instanceof UncheckedIOException ? (Exception) exception.getCause() : exception; + if (checkTimeout(e)) { + boolean readErrorOnClose = !isNoReadErrorOnClose(); + closeConnection(true); + if (!(e instanceof SoftEndOfStreamException)) { + if (e instanceof SocketTimeoutException) { + if (logger.isDebugEnabled()) { + logger.debug("Closed socket after timeout:" + getConnectionId()); + } + } + else { + logOtherExceptions(e, readErrorOnClose); + } + sendExceptionToListener(e); + } + return true; + } + return false; + } + + /* + * For client connections, we have to wait for 2 timeouts if the last + * send was within the current timeout. + */ + private boolean checkTimeout(Exception e) { boolean doClose = true; - /* - * For client connections, we have to wait for 2 timeouts if the last - * send was within the current timeout. - */ if (!isServer() && e instanceof SocketTimeoutException) { long now = System.currentTimeMillis(); try { @@ -234,43 +263,26 @@ public class TcpNetConnection extends TcpConnectionSupport implements Scheduling logger.error("Error accessing soTimeout", e1); } } - if (doClose) { - boolean noReadErrorOnClose = isNoReadErrorOnClose(); - closeConnection(true); - if (!(e instanceof SoftEndOfStreamException)) { - if (e instanceof SocketTimeoutException) { - if (logger.isDebugEnabled()) { - logger.debug("Closed socket after timeout:" + getConnectionId()); - } - } - else { - if (noReadErrorOnClose) { - if (logger.isTraceEnabled()) { - logger.trace("Read exception " + - getConnectionId(), e); - } - else if (logger.isDebugEnabled()) { - logger.debug("Read exception " + - getConnectionId() + " " + - e.getClass().getSimpleName() + - ":" + (e.getCause() != null ? e.getCause() + ":" : "") + e.getMessage()); - } - } - else if (logger.isTraceEnabled()) { - logger.error("Read exception " + - getConnectionId(), e); - } - else { - logger.error("Read exception " + - getConnectionId() + " " + - e.getClass().getSimpleName() + - ":" + (e.getCause() != null ? e.getCause() + ":" : "") + e.getMessage()); - } - } - sendExceptionToListener(e); - } - } return doClose; } + private void logOtherExceptions(Exception e, boolean readErrorOnClose) { + if (this.logger.isErrorEnabled()) { + String messagePrefix = "Read exception " + getConnectionId(); + Supplier summaryMessageSupplier = () -> messagePrefix + " " + e.getClass().getSimpleName() + ":" + + (e.getCause() != null ? e.getCause() + ":" : "") + e.getMessage(); + if (logger.isTraceEnabled()) { + logger.trace(messagePrefix, e); + } + else if (readErrorOnClose) { + logger.error(summaryMessageSupplier.get()); + } + else { + if (logger.isDebugEnabled()) { + logger.debug(summaryMessageSupplier.get()); + } + } + } + } + } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupport.java index ed07819668..e1a99dec91 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 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,11 +41,10 @@ public interface TcpNetConnectionSupport { * @param connectionFactoryName the name of the connection factory creating this connection; used * during event publishing, may be null, in which case "unknown" will be used. * @return the TcpNetConnection - * @throws Exception Any exception. */ TcpNetConnection createNewConnection(Socket socket, boolean server, boolean lookupHost, ApplicationEventPublisher applicationEventPublisher, - String connectionFactoryName) throws Exception; + String connectionFactoryName); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetServerConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetServerConnectionFactory.java index b6ae6eaa5c..adbd82a140 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetServerConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetServerConnectionFactory.java @@ -135,7 +135,7 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto socket = this.serverSocket.accept(); } } - catch (SocketTimeoutException ste) { + catch (@SuppressWarnings("unused") SocketTimeoutException ste) { if (logger.isDebugEnabled()) { logger.debug("Timed out on accept; continuing"); } @@ -164,20 +164,20 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto harvestClosedConnections(); connection.publishConnectionOpenEvent(); } - catch (Exception e) { + catch (RuntimeException e) { this.logger.error("Failed to create and configure a TcpConnection for the new socket: " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort(), e); try { socket.close(); } - catch (IOException e1) { + catch (@SuppressWarnings("unused") IOException e1) { // empty } } } } } - catch (Exception e) { + catch (IOException e) { // NOSONAR flow control via exceptions // don't log an error if we had a good socket once and now it's closed if (e instanceof SocketException && theServerSocket != null) { logger.info("Server Socket closed"); @@ -224,7 +224,7 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto try { this.serverSocket.close(); } - catch (IOException e) { + catch (@SuppressWarnings("unused") IOException e) { } this.serverSocket = null; super.stop(); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioClientConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioClientConnectionFactory.java index 0a7764971a..582635d90f 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioClientConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioClientConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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.integration.ip.tcp.connection; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.InetSocketAddress; import java.nio.channels.CancelledKeyException; import java.nio.channels.ClosedChannelException; @@ -63,43 +64,48 @@ public class TcpNioClientConnectionFactory extends } @Override - protected void checkActive() throws IOException { + protected void checkActive() { super.checkActive(); int n = 0; while (this.selector == null) { try { Thread.sleep(100); } - catch (InterruptedException e) { + catch (@SuppressWarnings("unused") InterruptedException e) { Thread.currentThread().interrupt(); } if (n++ > 600) { - throw new IOException("Factory failed to start"); + throw new UncheckedIOException(new IOException("Factory failed to start")); } } } @Override - protected TcpConnectionSupport buildNewConnection() throws Exception { - SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(getHost(), getPort())); - setSocketAttributes(socketChannel.socket()); - TcpNioConnection connection = this.tcpNioConnectionSupport.createNewConnection( - socketChannel, false, this.isLookupHost(), this.getApplicationEventPublisher(), getComponentName()); - connection.setUsingDirectBuffers(this.usingDirectBuffers); - connection.setTaskExecutor(this.getTaskExecutor()); - if (getSslHandshakeTimeout() != null && connection instanceof TcpNioSSLConnection) { - ((TcpNioSSLConnection) connection).setHandshakeTimeout(getSslHandshakeTimeout()); + protected TcpConnectionSupport buildNewConnection() { + try { + SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(getHost(), getPort())); + setSocketAttributes(socketChannel.socket()); + TcpNioConnection connection = this.tcpNioConnectionSupport.createNewConnection( + socketChannel, false, this.isLookupHost(), this.getApplicationEventPublisher(), getComponentName()); + connection.setUsingDirectBuffers(this.usingDirectBuffers); + connection.setTaskExecutor(this.getTaskExecutor()); + if (getSslHandshakeTimeout() != null && connection instanceof TcpNioSSLConnection) { + ((TcpNioSSLConnection) connection).setHandshakeTimeout(getSslHandshakeTimeout()); + } + TcpConnectionSupport wrappedConnection = wrapConnection(connection); + initializeConnection(wrappedConnection, socketChannel.socket()); + socketChannel.configureBlocking(false); + if (this.getSoTimeout() > 0) { + connection.setLastRead(System.currentTimeMillis()); + } + this.channelMap.put(socketChannel, connection); + this.newChannels.add(socketChannel); + this.selector.wakeup(); + return wrappedConnection; } - TcpConnectionSupport wrappedConnection = wrapConnection(connection); - initializeConnection(wrappedConnection, socketChannel.socket()); - socketChannel.configureBlocking(false); - if (this.getSoTimeout() > 0) { - connection.setLastRead(System.currentTimeMillis()); + catch (IOException e) { + throw new UncheckedIOException(e); } - this.channelMap.put(socketChannel, connection); - this.newChannels.add(socketChannel); - this.selector.wakeup(); - return wrappedConnection; } /** @@ -164,7 +170,7 @@ public class TcpNioClientConnectionFactory extends } selectionCount = this.selector.select(timeout); } - catch (CancelledKeyException cke) { + catch (@SuppressWarnings("unused") CancelledKeyException cke) { if (logger.isDebugEnabled()) { logger.debug("CancelledKeyException during Selector.select()"); } @@ -173,7 +179,7 @@ public class TcpNioClientConnectionFactory extends try { newChannel.register(this.selector, SelectionKey.OP_READ, this.channelMap.get(newChannel)); } - catch (ClosedChannelException cce) { + catch (@SuppressWarnings("unused") ClosedChannelException cce) { if (logger.isDebugEnabled()) { logger.debug("Channel closed before registering with selector for reading"); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnection.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnection.java index dc184219d0..def3484bba 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnection.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnection.java @@ -20,6 +20,7 @@ import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.net.SocketTimeoutException; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; @@ -57,6 +58,10 @@ import org.springframework.util.Assert; */ public class TcpNioConnection extends TcpConnectionSupport { + private static final String UNUSED = "unused"; + + private static final int SIXTY = 60; + private static final long DEFAULT_PIPE_TIMEOUT = 60000; private static final byte[] EOF = new byte[0]; // EOF marker buffer @@ -123,12 +128,12 @@ public class TcpNioConnection extends TcpConnectionSupport { try { this.channelInputStream.close(); } - catch (IOException e) { + catch (@SuppressWarnings(UNUSED) IOException e) { } try { this.socketChannel.close(); } - catch (Exception e) { + catch (@SuppressWarnings(UNUSED) Exception e) { } super.close(); } @@ -140,24 +145,25 @@ public class TcpNioConnection extends TcpConnectionSupport { @Override @SuppressWarnings("unchecked") - public void send(Message message) throws Exception { + public void send(Message message) { synchronized (this.socketChannel) { - if (this.bufferedOutputStream == null) { - int writeBufferSize = this.socketChannel.socket().getSendBufferSize(); - this.bufferedOutputStream = new BufferedOutputStream(getChannelOutputStream(), - writeBufferSize > 0 ? writeBufferSize : 8192); - } - Object object = getMapper().fromMessage(message); - Assert.state(object != null, "Mapper mapped the message to 'null'."); - this.lastSend = System.currentTimeMillis(); try { + if (this.bufferedOutputStream == null) { + int writeBufferSize = this.socketChannel.socket().getSendBufferSize(); + this.bufferedOutputStream = new BufferedOutputStream(getChannelOutputStream(), + writeBufferSize > 0 ? writeBufferSize : 8192); + } + Object object = getMapper().fromMessage(message); + Assert.state(object != null, "Mapper mapped the message to 'null'."); + this.lastSend = System.currentTimeMillis(); ((Serializer) getSerializer()).serialize(object, this.bufferedOutputStream); this.bufferedOutputStream.flush(); } catch (Exception e) { - publishConnectionExceptionEvent(new MessagingException(message, "Failed TCP serialization", e)); + MessagingException mex = new MessagingException(message, "Send Failed", e); + publishConnectionExceptionEvent(mex); closeConnection(true); - throw e; + throw mex; } if (logger.isDebugEnabled()) { logger.debug(getConnectionId() + " Message sent " + message); @@ -166,9 +172,14 @@ public class TcpNioConnection extends TcpConnectionSupport { } @Override - public Object getPayload() throws Exception { - return getDeserializer() - .deserialize(inputStream()); + public Object getPayload() { + try { + return getDeserializer() + .deserialize(inputStream()); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } } @Override @@ -240,7 +251,7 @@ public class TcpNioConnection extends TcpConnectionSupport { try { this.taskExecutor.execute2(this); } - catch (RejectedExecutionException e) { + catch (@SuppressWarnings(UNUSED) RejectedExecutionException e) { this.executionControl.decrementAndGet(); if (logger.isInfoEnabled()) { logger.info(getConnectionId() @@ -288,40 +299,35 @@ public class TcpNioConnection extends TcpConnectionSupport { // Final check in case new data came in and the // timing was such that we were the last assembler and // a new one wasn't run - try { - if (dataAvailable()) { - synchronized (this.executionControl) { - if (this.executionControl.incrementAndGet() <= 1) { - // only continue if we don't already have another assembler running - this.executionControl.set(1); - moreDataAvailable = true; + if (dataAvailable()) { + synchronized (this.executionControl) { + if (this.executionControl.incrementAndGet() <= 1) { + // only continue if we don't already have another assembler running + this.executionControl.set(1); + moreDataAvailable = true; - } - else { - this.executionControl.decrementAndGet(); - } } - } - if (moreDataAvailable) { - if (logger.isTraceEnabled()) { - logger.trace(getConnectionId() + " Nio message assembler continuing..."); - } - } - else { - if (logger.isTraceEnabled()) { - logger.trace(getConnectionId() + " Nio message assembler exiting... avail: " - + this.channelInputStream.available()); + else { + this.executionControl.decrementAndGet(); } } } - catch (IOException e) { - logger.error("Exception when checking for assembler", e); + if (moreDataAvailable) { + if (logger.isTraceEnabled()) { + logger.trace(getConnectionId() + " Nio message assembler continuing..."); + } + } + else { + if (logger.isTraceEnabled()) { + logger.trace(getConnectionId() + " Nio message assembler exiting... avail: " + + this.channelInputStream.available()); + } } } } } - private boolean dataAvailable() throws IOException { + private boolean dataAvailable() { if (logger.isTraceEnabled()) { logger.trace(getConnectionId() + " checking data avail: " + this.channelInputStream.available() + " pending: " + (this.writingToPipe)); @@ -343,7 +349,7 @@ public class TcpNioConnection extends TcpConnectionSupport { } if (this.channelInputStream.available() <= 0) { try { - if (this.writingLatch.await(60, TimeUnit.SECONDS)) { + if (this.writingLatch.await(SIXTY, TimeUnit.SECONDS)) { if (this.channelInputStream.available() <= 0) { return null; } @@ -352,7 +358,7 @@ public class TcpNioConnection extends TcpConnectionSupport { throw new IOException("Timed out waiting for IO"); } } - catch (InterruptedException e) { + catch (@SuppressWarnings(UNUSED) InterruptedException e) { Thread.currentThread().interrupt(); throw new IOException("Interrupted waiting for IO"); } @@ -451,13 +457,13 @@ public class TcpNioConnection extends TcpConnectionSupport { } } - protected void sendToPipe(ByteBuffer rawBuffer) throws IOException { - Assert.notNull(rawBuffer, "rawBuffer cannot be null"); + protected void sendToPipe(ByteBuffer rawBufferToSend) throws IOException { + Assert.notNull(rawBufferToSend, "rawBuffer cannot be null"); if (logger.isTraceEnabled()) { - logger.trace(getConnectionId() + " Sending " + rawBuffer.limit() + " to pipe"); + logger.trace(getConnectionId() + " Sending " + rawBufferToSend.limit() + " to pipe"); } - this.channelInputStream.write(rawBuffer); - rawBuffer.clear(); + this.channelInputStream.write(rawBufferToSend); + rawBufferToSend.clear(); } private void checkForAssembler() { @@ -496,7 +502,7 @@ public class TcpNioConnection extends TcpConnectionSupport { try { doRead(); } - catch (ClosedChannelException cce) { + catch (@SuppressWarnings(UNUSED) ClosedChannelException cce) { if (logger.isDebugEnabled()) { logger.debug(getConnectionId() + " Channel is closed"); } @@ -593,12 +599,12 @@ public class TcpNioConnection extends TcpConnectionSupport { } @Override - public void close() throws IOException { + public void close() { doClose(); } @Override - public void flush() throws IOException { + public void flush() { } @Override @@ -767,7 +773,7 @@ public class TcpNioConnection extends TcpConnectionSupport { try { this.buffers.offer(EOF, TcpNioConnection.this.pipeTimeout, TimeUnit.SECONDS); } - catch (InterruptedException e) { + catch (@SuppressWarnings(UNUSED) InterruptedException e) { Thread.currentThread().interrupt(); } } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionSupport.java index 912bece200..d093516b5e 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,11 +42,10 @@ public interface TcpNioConnectionSupport { * @param connectionFactoryName the name of the connection factory creating this connection; used * during event publishing, may be null, in which case "unknown" will be used. * @return the TcpNioConnection - * @throws Exception Any exception. */ TcpNioConnection createNewConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, ApplicationEventPublisher applicationEventPublisher, - String connectionFactoryName) throws Exception; + String connectionFactoryName); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioSSLConnection.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioSSLConnection.java index 8850be473a..fc46b60d6a 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioSSLConnection.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioSSLConnection.java @@ -17,6 +17,7 @@ package org.springframework.integration.ip.tcp.connection; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.concurrent.Semaphore; @@ -82,7 +83,7 @@ public class TcpNioSSLConnection extends TcpNioConnection { public TcpNioSSLConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, ApplicationEventPublisher applicationEventPublisher, @Nullable String connectionFactoryName, - SSLEngine sslEngine) throws Exception { + SSLEngine sslEngine) { super(socketChannel, server, lookupHost, applicationEventPublisher, connectionFactoryName); this.sslEngine = sslEngine; @@ -252,14 +253,17 @@ public class TcpNioSSLConnection extends TcpNioConnection { /** * Initializes the SSLEngine and sets up the encryption/decryption buffers. - * - * @throws IOException Any IOException. */ - public void init() throws IOException { + public void init() { if (this.decoded == null) { this.decoded = allocateEncryptionBuffer(2048); this.encoded = allocateEncryptionBuffer(2048); - initilizeEngine(); + try { + initilizeEngine(); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } } } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioServerConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioServerConnectionFactory.java index a53f8cec9d..67878aa61d 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioServerConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioServerConnectionFactory.java @@ -17,6 +17,7 @@ package org.springframework.integration.ip.tcp.connection; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; @@ -80,6 +81,7 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto } } catch (IOException e) { + logger.error("Error getting port", e); } } return port; @@ -93,6 +95,7 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto return this.serverChannel.getLocalAddress(); } catch (IOException e) { + logger.error("Error getting local address", e); } } return null; @@ -161,10 +164,10 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto * schedules a call to doRead which reads all available data. When the read * is complete, the socket is again registered for read interest. * @param server the ServerSocketChannel to select - * @param selector the Selector multiplexor + * @param selectorToSelect the Selector multiplexor * @throws IOException */ - private void doSelect(ServerSocketChannel server, final Selector selector) throws IOException { + private void doSelect(ServerSocketChannel server, final Selector selectorToSelect) throws IOException { while (isActive()) { int soTimeout = getSoTimeout(); int selectionCount = 0; @@ -176,10 +179,10 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto if (logger.isTraceEnabled()) { logger.trace("Delayed reads: " + getDelayedReads().size() + " timeout " + timeout); } - selectionCount = selector.select(timeout); - processNioSelections(selectionCount, selector, server, this.channelMap); + selectionCount = selectorToSelect.select(timeout); + processNioSelections(selectionCount, selectorToSelect, server, this.channelMap); } - catch (CancelledKeyException cke) { + catch (@SuppressWarnings("unused") CancelledKeyException cke) { logger.debug("CancelledKeyException during Selector.select()"); } catch (ClosedSelectorException cse) { @@ -193,47 +196,51 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto } /** - * @param selector The selector. + * @param selectorForNewSocket The selector. * @param server The server socket channel. * @param now The current time. - * @throws IOException Any IOException. */ @Override - protected void doAccept(final Selector selector, ServerSocketChannel server, long now) throws IOException { + protected void doAccept(final Selector selectorForNewSocket, ServerSocketChannel server, long now) { logger.debug("New accept"); - SocketChannel channel = server.accept(); - if (isShuttingDown()) { - if (logger.isInfoEnabled()) { - logger.info("New connection from " + channel.socket().getInetAddress().getHostAddress() - + ":" + channel.socket().getPort() - + " rejected; the server is in the process of shutting down."); - } - channel.close(); - } - else { - try { - channel.configureBlocking(false); - Socket socket = channel.socket(); - setSocketAttributes(socket); - TcpNioConnection connection = createTcpNioConnection(channel); - if (connection == null) { - return; + try { + SocketChannel channel = server.accept(); + if (isShuttingDown()) { + if (logger.isInfoEnabled()) { + logger.info("New connection from " + channel.socket().getInetAddress().getHostAddress() + + ":" + channel.socket().getPort() + + " rejected; the server is in the process of shutting down."); } - connection.setTaskExecutor(getTaskExecutor()); - connection.setLastRead(now); - if (getSslHandshakeTimeout() != null && connection instanceof TcpNioSSLConnection) { - ((TcpNioSSLConnection) connection).setHandshakeTimeout(getSslHandshakeTimeout()); - } - this.channelMap.put(channel, connection); - channel.register(selector, SelectionKey.OP_READ, connection); - connection.publishConnectionOpenEvent(); - } - catch (Exception e) { - logger.error("Exception accepting new connection from " - + channel.socket().getInetAddress().getHostAddress() - + ":" + channel.socket().getPort(), e); channel.close(); } + else { + try { + channel.configureBlocking(false); + Socket socket = channel.socket(); + setSocketAttributes(socket); + TcpNioConnection connection = createTcpNioConnection(channel); + if (connection == null) { + return; + } + connection.setTaskExecutor(getTaskExecutor()); + connection.setLastRead(now); + if (getSslHandshakeTimeout() != null && connection instanceof TcpNioSSLConnection) { + ((TcpNioSSLConnection) connection).setHandshakeTimeout(getSslHandshakeTimeout()); + } + this.channelMap.put(channel, connection); + channel.register(selectorForNewSocket, SelectionKey.OP_READ, connection); + connection.publishConnectionOpenEvent(); + } + catch (IOException e) { + logger.error("Exception accepting new connection from " + + channel.socket().getInetAddress().getHostAddress() + + ":" + channel.socket().getPort(), e); + channel.close(); + } + } + } + catch (IOException e) { + throw new UncheckedIOException(e); } } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/ThreadAffinityClientConnectionFactory.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/ThreadAffinityClientConnectionFactory.java index 1faa252d0a..f7fa235d67 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/ThreadAffinityClientConnectionFactory.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/ThreadAffinityClientConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 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 ThreadAffinityClientConnectionFactory extends AbstractClientConnect } @Override - public TcpConnectionSupport getConnection() throws Exception { + public TcpConnectionSupport getConnection() throws InterruptedException { TcpThreadConnection connection = this.connections.get(); if (connection == null || !connection.isOpen()) { TcpConnectionSupport delegate = this.connectionFactory.getConnection(); @@ -380,7 +380,7 @@ public class ThreadAffinityClientConnectionFactory extends AbstractClientConnect } @Override - public void send(Message message) throws Exception { + public void send(Message message) { this.connection.send(message); } @@ -390,7 +390,7 @@ public class ThreadAffinityClientConnectionFactory extends AbstractClientConnect } @Override - public Object getPayload() throws Exception { + public Object getPayload() { return this.connection.getPayload(); } diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/DatagramPacketMessageMapper.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/DatagramPacketMessageMapper.java index 93ef7c379f..2c017bcb01 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/DatagramPacketMessageMapper.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/DatagramPacketMessageMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -39,6 +39,7 @@ import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandlingException; import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.MessagingException; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -133,7 +134,7 @@ public class DatagramPacketMessageMapper implements InboundMessageMapper message) throws Exception { + public DatagramPacket fromMessage(Message message) { if (this.acknowledge) { return fromMessageWithAck(message); } @@ -152,23 +153,28 @@ public class DatagramPacketMessageMapper implements InboundMessageMapper message) throws Exception { + private DatagramPacket fromMessageWithAck(Message message) { Assert.state(StringUtils.hasText(this.ackAddress), "'ackAddress' must not be empty"); byte[] bytes = getPayloadAsBytes(message); ByteBuffer buffer = ByteBuffer.allocate(100 + bytes.length); if (this.lengthCheck) { buffer.putInt(0); // placeholder for length } - buffer.put(IpHeaders.ACK_ADDRESS.getBytes(this.charset)); - buffer.put((byte) '='); - buffer.put(this.ackAddress.getBytes(this.charset)); - buffer.put((byte) ';'); - UUID id = message.getHeaders().getId(); - if (id != null) { - buffer.put(MessageHeaders.ID.getBytes(this.charset)); + try { + buffer.put(IpHeaders.ACK_ADDRESS.getBytes(this.charset)); buffer.put((byte) '='); - buffer.put(id.toString().getBytes(this.charset)); + buffer.put(this.ackAddress.getBytes(this.charset)); buffer.put((byte) ';'); + UUID id = message.getHeaders().getId(); + if (id != null) { + buffer.put(MessageHeaders.ID.getBytes(this.charset)); + buffer.put((byte) '='); + buffer.put(id.toString().getBytes(this.charset)); + buffer.put((byte) ';'); + } + } + catch (UnsupportedEncodingException e) { + throw new MessagingException(message, "Failed to get headers", e); } int headersLength = buffer.position() - 4; buffer.put(bytes); @@ -203,13 +209,13 @@ public class DatagramPacketMessageMapper implements InboundMessageMapper toMessage(DatagramPacket object) throws Exception { + public Message toMessage(DatagramPacket object) { return toMessage(object, null); } @Override @Nullable - public Message toMessage(DatagramPacket packet, @Nullable Map headers) throws Exception { + public Message toMessage(DatagramPacket packet, @Nullable Map headers) { int offset = packet.getOffset(); int length = packet.getLength(); byte[] payload; diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/MulticastSendingMessageHandler.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/MulticastSendingMessageHandler.java index 113c739012..6f88e03120 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/MulticastSendingMessageHandler.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/MulticastSendingMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2018 the original author or authors. + * Copyright 2001-2019 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. @@ -21,6 +21,7 @@ import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.MulticastSocket; +import java.net.URISyntaxException; import org.springframework.expression.Expression; import org.springframework.messaging.Message; @@ -190,7 +191,7 @@ public class MulticastSendingMessageHandler extends UnicastSendingMessageHandler } @Override - protected void convertAndSend(Message message) throws Exception { + protected void convertAndSend(Message message) throws IOException, URISyntaxException { super.convertAndSend(message); if (logger.isDebugEnabled()) { logger.debug("Sent packet to " + this.multicastSocket.getInterface()); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastReceivingChannelAdapter.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastReceivingChannelAdapter.java index 30515e452a..aeb792c85f 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastReceivingChannelAdapter.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastReceivingChannelAdapter.java @@ -217,7 +217,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece } } - protected DatagramPacket receive() throws Exception { + protected DatagramPacket receive() throws IOException { final byte[] buffer = new byte[this.getReceiveBufferSize()]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); getSocket().receive(packet); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastSendingMessageHandler.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastSendingMessageHandler.java index ef24c0b349..29cb0b47ca 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastSendingMessageHandler.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/udp/UnicastSendingMessageHandler.java @@ -24,6 +24,7 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.SocketException; import java.net.URI; +import java.net.URISyntaxException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -278,7 +279,7 @@ public class UnicastSendingMessageHandler extends + this.ackTimeout + " millis"); } } - catch (InterruptedException e) { + catch (@SuppressWarnings("unused") InterruptedException e) { Thread.currentThread().interrupt(); } } @@ -312,7 +313,7 @@ public class UnicastSendingMessageHandler extends try { this.ackLatch.await(10000, TimeUnit.MILLISECONDS); } - catch (InterruptedException e) { + catch (@SuppressWarnings("unused") InterruptedException e) { Thread.currentThread().interrupt(); } } @@ -320,7 +321,7 @@ public class UnicastSendingMessageHandler extends } } - protected void convertAndSend(Message message) throws Exception { + protected void convertAndSend(Message message) throws IOException, URISyntaxException { DatagramSocket datagramSocket; if (this.socketExpression != null) { datagramSocket = this.socketExpression.getValue(this.evaluationContext, message, DatagramSocket.class); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/util/TestingUtilities.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/util/TestingUtilities.java index b90e5ad223..caa4779565 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/util/TestingUtilities.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/util/TestingUtilities.java @@ -139,10 +139,12 @@ public final class TestingUtilities { * of connections. * @param factory The factory. * @param n The required number of connections. - * @throws Exception IllegalStateException if the count does not match. + * @throws InterruptedException if interrupted. + * @throws IllegalStateException if the count does not match. */ public static void waitUntilFactoryHasThisNumberOfConnections(AbstractConnectionFactory factory, int n) - throws Exception { + throws InterruptedException { + int timer = 0; while (timer < 10000) { if (factory.getOpenConnectionIds().size() == n) { diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests.java index edfae92200..967c55bafb 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests.java @@ -653,7 +653,7 @@ public class ParserUnitTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled.countDown(); return null; } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpOutboundGatewayTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpOutboundGatewayTests.java index 78eaae56ea..8d92536849 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpOutboundGatewayTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpOutboundGatewayTests.java @@ -17,6 +17,7 @@ package org.springframework.integration.ip.tcp; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; import static org.assertj.core.api.Assertions.fail; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -27,6 +28,7 @@ import java.io.EOFException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.UncheckedIOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; @@ -74,6 +76,8 @@ import org.springframework.integration.test.rule.Log4j2LevelAdjuster; import org.springframework.integration.test.support.LongRunningIntegrationTest; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHandlingException; +import org.springframework.messaging.MessagingException; import org.springframework.messaging.PollableChannel; import org.springframework.messaging.support.ErrorMessage; import org.springframework.messaging.support.GenericMessage; @@ -485,7 +489,8 @@ public class TcpOutboundGatewayTests { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); TcpConnectionSupport mockConn1 = makeMockConnection(); when(factory1.getConnection()).thenReturn(mockConn1); - doThrow(new IOException("fail")).when(mockConn1).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))) + .when(mockConn1).send(Mockito.any(Message.class)); AbstractClientConnectionFactory factory2 = new TcpNetClientConnectionFactory("localhost", serverSocket.get().getLocalPort()); @@ -567,7 +572,8 @@ public class TcpOutboundGatewayTests { TcpConnectionSupport mockConn1 = makeMockConnection(); when(factory1.getConnection()).thenReturn(mockConn1); when(factory1.isSingleUse()).thenReturn(true); - doThrow(new IOException("fail")).when(mockConn1).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))) + .when(mockConn1).send(Mockito.any(Message.class)); CachingClientConnectionFactory cachingFactory1 = new CachingClientConnectionFactory(factory1, 1); AbstractClientConnectionFactory factory2 = new TcpNetClientConnectionFactory("localhost", @@ -727,13 +733,10 @@ public class TcpOutboundGatewayTests { gateway.setBeanFactory(mock(BeanFactory.class)); gateway.afterPropertiesSet(); gateway.start(); - try { - gateway.handleMessage(MessageBuilder.withPayload("Test").build()); - fail("expected failure"); - } - catch (Exception e) { - assertThat(e.getCause().getCause()).isInstanceOf(EOFException.class); - } + Throwable thrown = catchThrowable(() -> gateway.handleMessage(MessageBuilder.withPayload("Test").build())); + assertThat(thrown).isInstanceOf(MessageHandlingException.class); + assertThat(thrown.getCause()).isInstanceOf(MessagingException.class); + assertThat(thrown.getCause().getCause()).isInstanceOf(EOFException.class); assertThat(TestUtils.getPropertyValue(gateway, "pendingReplies", Map.class).size()).isEqualTo(0); Message reply = replyChannel.receive(0); assertThat(reply).isNull(); @@ -837,13 +840,10 @@ public class TcpOutboundGatewayTests { gateway.setBeanFactory(mock(BeanFactory.class)); gateway.afterPropertiesSet(); gateway.start(); - try { - gateway.handleMessage(MessageBuilder.withPayload("Test").build()); - fail("expected failure"); - } - catch (Exception e) { - assertThat(e.getCause().getCause()).isInstanceOf(SocketTimeoutException.class); - } + Throwable thrown = catchThrowable(() -> gateway.handleMessage(MessageBuilder.withPayload("Test").build())); + assertThat(thrown).isInstanceOf(MessageHandlingException.class); + assertThat(thrown.getCause()).isInstanceOf(MessagingException.class); + assertThat(thrown.getCause().getCause()).isInstanceOf(SocketTimeoutException.class); assertThat(TestUtils.getPropertyValue(gateway, "pendingReplies", Map.class).size()).isEqualTo(0); Message reply = replyChannel.receive(0); assertThat(reply).isNull(); diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactoryTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactoryTests.java index d4cc8ba24f..8bb6ba7f78 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactoryTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/CachingClientConnectionFactoryTests.java @@ -17,7 +17,7 @@ package org.springframework.integration.ip.tcp.connection; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -32,6 +32,7 @@ import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; @@ -73,6 +74,7 @@ import org.springframework.integration.test.util.TestUtils; import org.springframework.integration.util.PoolItemNotAvailableException; import org.springframework.integration.util.SimplePool; import org.springframework.messaging.Message; +import org.springframework.messaging.MessagingException; import org.springframework.messaging.PollableChannel; import org.springframework.messaging.SubscribableChannel; import org.springframework.messaging.support.ErrorMessage; @@ -363,13 +365,8 @@ public class CachingClientConnectionFactoryTests { private void doTestCloseOnSendError(TcpConnection conn1, TcpConnection conn2, CachingClientConnectionFactory cccf) throws Exception { TcpConnection cached1 = cccf.getConnection(); - try { - cached1.send(new GenericMessage("foo")); - fail("Expected IOException"); - } - catch (IOException e) { - assertThat(e.getMessage()).isEqualTo("Foo"); - } + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> cached1.send(new GenericMessage("foo"))); // Before INT-3163 this failed with a timeout - connection not returned to pool after failure on send() TcpConnection cached2 = cccf.getConnection(); assertThat(cached1.getConnectionId().contains(conn1.getConnectionId())).isTrue(); @@ -550,7 +547,7 @@ public class CachingClientConnectionFactoryTests { when(factory2.getConnection()).thenReturn(mockConn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); - doThrow(new IOException("fail")).when(mockConn1).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))).when(mockConn1).send(Mockito.any(Message.class)); doAnswer(invocation -> null).when(mockConn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionEventTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionEventTests.java index ad5be5efaa..609de7bc1a 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionEventTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionEventTests.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; @@ -258,13 +259,7 @@ public class ConnectionEventTests { } private void testServerExceptionGuts(AbstractServerConnectionFactory factory) throws Exception { - ServerSocket ss = null; - try { - ss = ServerSocketFactory.getDefault().createServerSocket(0); - } - catch (Exception e) { - fail("Failed to get a server socket"); - } + ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(0); factory.setPort(ss.getLocalPort()); final AtomicReference theEvent = new AtomicReference(); @@ -315,8 +310,8 @@ public class ConnectionEventTests { } @Override - protected TcpConnectionSupport buildNewConnection() throws Exception { - throw new UnknownHostException("Mocking for test "); + protected TcpConnectionSupport buildNewConnection() { + throw new UncheckedIOException(new UnknownHostException("Mocking for test ")); } }; @@ -340,7 +335,7 @@ public class ConnectionEventTests { fail("expected exception"); } catch (Exception e) { - assertThat(e).isInstanceOf(UnknownHostException.class); + assertThat(e.getCause()).isInstanceOf(UnknownHostException.class); TcpConnectionFailedEvent event = (TcpConnectionFailedEvent) failEvent.get(); assertThat(event.getCause()).isSameAs(e); } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionTimeoutTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionTimeoutTests.java index 33916ea7fe..f2568a006e 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionTimeoutTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/ConnectionTimeoutTests.java @@ -171,7 +171,7 @@ public class ConnectionTimeoutTests { connection.send(MessageBuilder.withPayload("foo").build()); Thread.sleep(1400); assertThat(connection.isOpen()).isTrue(); - assertThat(clientCloseLatch.await(2000, TimeUnit.SECONDS)).isTrue(); + assertThat(clientCloseLatch.await(5, TimeUnit.SECONDS)).isTrue(); assertThat(reply.get()).isNull(); assertThat(connection.isOpen()).isFalse(); server.stop(); diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactoryTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactoryTests.java index 249c70daf4..768ff9e3bc 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactoryTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/FailoverClientConnectionFactoryTests.java @@ -17,7 +17,7 @@ package org.springframework.integration.ip.tcp.connection; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -25,6 +25,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.Socket; import java.nio.channels.SocketChannel; import java.util.ArrayList; @@ -100,7 +101,8 @@ public class FailoverClientConnectionFactoryTests { when(factory2.getConnection()).thenReturn(conn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); - doThrow(new IOException("fail")).when(conn1).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))) + .when(conn1).send(Mockito.any(Message.class)); doAnswer(invocation -> null).when(conn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); @@ -109,7 +111,7 @@ public class FailoverClientConnectionFactoryTests { Mockito.verify(conn2).send(message); } - @Test(expected = IOException.class) + @Test(expected = UncheckedIOException.class) public void testFailoverAllDead() throws Exception { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); @@ -122,8 +124,10 @@ public class FailoverClientConnectionFactoryTests { when(factory2.getConnection()).thenReturn(conn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); - doThrow(new IOException("fail")).when(conn1).send(Mockito.any(Message.class)); - doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))) + .when(conn1).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))) + .when(conn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage message = new GenericMessage("foo"); @@ -148,11 +152,12 @@ public class FailoverClientConnectionFactoryTests { doAnswer(invocation -> { if (!failedOnce.get()) { failedOnce.set(true); - throw new IOException("fail"); + throw new UncheckedIOException(new IOException("fail")); } return null; }).when(conn1).send(Mockito.any(Message.class)); - doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))) + .when(conn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage message = new GenericMessage("foo"); @@ -161,15 +166,15 @@ public class FailoverClientConnectionFactoryTests { Mockito.verify(conn1, times(2)).send(message); } - @Test(expected = IOException.class) + @Test(expected = UncheckedIOException.class) public void testFailoverConnectNone() throws Exception { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); List factories = new ArrayList(); factories.add(factory1); factories.add(factory2); - when(factory1.getConnection()).thenThrow(new IOException("fail")); - when(factory2.getConnection()).thenThrow(new IOException("fail")); + when(factory1.getConnection()).thenThrow(new UncheckedIOException(new IOException("fail"))); + when(factory2.getConnection()).thenThrow(new UncheckedIOException(new IOException("fail"))); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); @@ -187,8 +192,11 @@ public class FailoverClientConnectionFactoryTests { factories.add(factory2); TcpConnectionSupport conn1 = makeMockConnection(); doAnswer(invocation -> null).when(conn1).send(Mockito.any(Message.class)); - when(factory1.getConnection()).thenThrow(new IOException("fail")).thenReturn(conn1); - when(factory2.getConnection()).thenThrow(new IOException("fail")); + when(factory1.getConnection()) + .thenThrow(new UncheckedIOException(new IOException("fail"))) + .thenReturn(conn1); + when(factory2.getConnection()) + .thenThrow(new UncheckedIOException(new IOException("fail"))); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); @@ -214,20 +222,17 @@ public class FailoverClientConnectionFactoryTests { final AtomicInteger failCount = new AtomicInteger(); doAnswer(invocation -> { if (failCount.incrementAndGet() < 3) { - throw new IOException("fail"); + throw new UncheckedIOException(new IOException("fail")); } return null; }).when(conn1).send(Mockito.any(Message.class)); - doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class)); + doThrow(new UncheckedIOException(new IOException("fail"))) + .when(conn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage message = new GenericMessage("foo"); - try { - failoverFactory.getConnection().send(message); - fail("ExpectedFailure"); - } - catch (IOException e) { - } + assertThatExceptionOfType(UncheckedIOException.class) + .isThrownBy(() -> failoverFactory.getConnection().send(message)); failoverFactory.getConnection().send(message); Mockito.verify(conn2).send(message); Mockito.verify(conn1, times(3)).send(message); diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java index 38d45d7382..79196698a7 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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,9 +19,6 @@ package org.springframework.integration.ip.tcp.connection; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import org.springframework.context.ApplicationEventPublisher; import org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.Message; @@ -34,8 +31,6 @@ import org.springframework.messaging.MessagingException; */ public class HelloWorldInterceptor extends TcpConnectionInterceptorSupport { - Log logger = LogFactory.getLog(this.getClass()); - private volatile boolean negotiated; private final Semaphore negotiationSemaphore = new Semaphore(0); @@ -109,14 +104,19 @@ public class HelloWorldInterceptor extends TcpConnectionInterceptorSupport { } @Override - public void send(Message message) throws Exception { + public void send(Message message) { this.pendingSend = true; try { if (!this.negotiated) { if (!this.isServer()) { logger.debug(this.toString() + " Sending " + hello); super.send(MessageBuilder.withPayload(hello).build()); - this.negotiationSemaphore.tryAcquire(this.timeout, TimeUnit.MILLISECONDS); + try { + this.negotiationSemaphore.tryAcquire(this.timeout, TimeUnit.MILLISECONDS); + } + catch (@SuppressWarnings("unused") InterruptedException e) { + Thread.currentThread().interrupt(); + } if (!this.negotiated) { throw new MessagingException("Negotiation error"); } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/SocketSupportTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/SocketSupportTests.java index bbd59a86d1..b86c47e462 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/SocketSupportTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/SocketSupportTests.java @@ -17,18 +17,15 @@ package org.springframework.integration.ip.tcp.connection; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; -import java.net.SocketException; -import java.nio.channels.ClosedChannelException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -41,7 +38,6 @@ import java.util.concurrent.atomic.AtomicReference; import javax.net.ServerSocketFactory; import javax.net.SocketFactory; import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLException; import javax.net.ssl.SSLServerSocket; import org.junit.Test; @@ -51,6 +47,7 @@ import org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer import org.springframework.integration.ip.util.TestingUtilities; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.Message; +import org.springframework.messaging.MessagingException; import org.springframework.messaging.support.GenericMessage; /** @@ -366,13 +363,8 @@ public class SocketSupportTests { @Test public void testNetClientAndServerSSLDifferentContexts() throws Exception { testNetClientAndServerSSLDifferentContexts(false); - try { - testNetClientAndServerSSLDifferentContexts(true); - fail("expected Exception"); - } - catch (SSLException | SocketException e) { - // NOSONAR - } + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> testNetClientAndServerSSLDifferentContexts(true)); } private void testNetClientAndServerSSLDifferentContexts(boolean badClient) throws Exception { @@ -478,19 +470,10 @@ public class SocketSupportTests { @Test public void testNioClientAndServerSSLDifferentContexts() throws Exception { testNioClientAndServerSSLDifferentContexts(false); - try { - testNioClientAndServerSSLDifferentContexts(true); - fail("expected Exception"); - } - catch (IOException e) { - if (!(e instanceof ClosedChannelException)) { - assertThat(e.getMessage()) - .satisfiesAnyOf( - s -> assertThat(s).contains("Socket closed during SSL Handshake"), - s -> assertThat(s).contains("Broken pipe"), - s -> assertThat(s).contains("Connection reset by peer")); - } - } + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> testNioClientAndServerSSLDifferentContexts(true)) + .withMessageMatching(".*(Socket closed during SSL Handshake|Broken pipe" + + "|Connection reset by peer|AsynchronousCloseException).*"); } private void testNioClientAndServerSSLDifferentContexts(boolean badClient) throws Exception { diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpMessageMapperTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpMessageMapperTests.java index d36f64c388..9789d070a1 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpMessageMapperTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpMessageMapperTests.java @@ -146,7 +146,7 @@ public class TcpMessageMapperTests { } @Test(expected = IllegalArgumentException.class) - public void testToMessageWithBadContentType() throws Exception { + public void testToMessageWithBadContentType() { TcpMessageMapper mapper = new TcpMessageMapper(); mapper.setAddContentTypeHeader(true); try { @@ -169,7 +169,7 @@ public class TcpMessageMapperTests { } @Override - public void send(Message message) throws Exception { + public void send(Message message) { } @Override @@ -183,7 +183,7 @@ public class TcpMessageMapperTests { } @Override - public Object getPayload() throws Exception { + public Object getPayload() { return TEST_PAYLOAD.getBytes(); } @@ -252,7 +252,7 @@ public class TcpMessageMapperTests { } @Override - public void send(Message message) throws Exception { + public void send(Message message) { } @Override @@ -266,7 +266,7 @@ public class TcpMessageMapperTests { } @Override - public Object getPayload() throws Exception { + public Object getPayload() { return TEST_PAYLOAD.getBytes(); } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupportTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupportTests.java index 64e933eda8..5218749a28 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupportTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2019 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. @@ -52,13 +52,13 @@ public class TcpNetConnectionSupportTests { server.setTcpNetConnectionSupport(new DefaultTcpNetConnectionSupport() { @Override - public TcpNetConnection createNewConnection(Socket socket, boolean server, boolean lookupHost, - ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) - throws Exception { + public TcpNetConnection createNewConnection(Socket socket, boolean isServer, boolean lookupHost, + ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) { + if (firstTime.getAndSet(false)) { throw new RuntimeException("intended"); } - return super.createNewConnection(socket, server, lookupHost, applicationEventPublisher, connectionFactoryName); + return super.createNewConnection(socket, isServer, lookupHost, applicationEventPublisher, connectionFactoryName); } }); diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionTests.java index 9803e6e556..bdcfa9a769 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNetConnectionTests.java @@ -17,6 +17,7 @@ package org.springframework.integration.ip.tcp.connection; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -63,6 +64,7 @@ public class TcpNetConnectionTests { connection.setDeserializer(new ByteArrayStxEtxSerializer()); final AtomicReference log = new AtomicReference(); Log logger = mock(Log.class); + given(logger.isErrorEnabled()).willReturn(true); doAnswer(invocation -> { log.set(invocation.getArguments()[0]); return null; diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionTests.java index 75c62f821b..291d0851f1 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/TcpNioConnectionTests.java @@ -83,6 +83,7 @@ import org.springframework.integration.test.rule.Log4j2LevelAdjuster; import org.springframework.integration.test.util.TestUtils; import org.springframework.integration.util.CompositeExecutor; import org.springframework.messaging.Message; +import org.springframework.messaging.MessagingException; import org.springframework.messaging.support.ErrorMessage; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.ReflectionUtils; @@ -143,8 +144,8 @@ public class TcpNioConnectionTests { TcpConnection connection = factory.getConnection(); connection.send(MessageBuilder.withPayload(new byte[1000000]).build()); } - catch (Exception e) { - assertThat(e instanceof SocketTimeoutException) + catch (MessagingException e) { + assertThat(e.getCause() instanceof SocketTimeoutException) .as("Expected SocketTimeoutException, got " + e.getClass().getSimpleName() + ":" + e.getMessage()).isTrue(); } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/udp/UdpChannelAdapterTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/udp/UdpChannelAdapterTests.java index 1dbb2a7ad2..56b43e2cda 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/udp/UdpChannelAdapterTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/udp/UdpChannelAdapterTests.java @@ -102,7 +102,7 @@ public class UdpChannelAdapterTests { } @Override - protected DatagramPacket receive() throws Exception { + protected DatagramPacket receive() throws IOException { if (stopping.get()) { return new DatagramPacket(new byte[0], 0); } diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java index fb260ff98a..08e5ce006e 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java @@ -160,7 +160,7 @@ public class JdbcMessageHandlerParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcOutboundGatewayParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcOutboundGatewayParserTests.java index 8d12f2cafd..41522a1873 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcOutboundGatewayParserTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcOutboundGatewayParserTests.java @@ -315,7 +315,7 @@ public class JdbcOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java index 81cdef004c..205b54099b 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java @@ -184,7 +184,7 @@ public class StoredProcMessageHandlerParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParserTests.java index 41a5700523..f0610b6148 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParserTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParserTests.java @@ -298,7 +298,7 @@ public class StoredProcOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java index 93a02586ae..fe10cf84f5 100644 --- a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java +++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java @@ -204,7 +204,7 @@ public class JmsOutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java index 960f6e1f57..046b71e72b 100644 --- a/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java +++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundGatewayParserTests.java @@ -290,7 +290,7 @@ public class JmsOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/NotificationPublishingMessageHandler.java b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/NotificationPublishingMessageHandler.java index caf303dbd4..4ede40102a 100644 --- a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/NotificationPublishingMessageHandler.java +++ b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/NotificationPublishingMessageHandler.java @@ -38,6 +38,7 @@ import org.springframework.jmx.export.notification.NotificationPublisherAware; import org.springframework.jmx.support.ObjectNameManager; import org.springframework.lang.Nullable; import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHandlingException; import org.springframework.util.Assert; /** @@ -134,8 +135,13 @@ public class NotificationPublishingMessageHandler extends AbstractMessageHandler } @Override - protected void handleMessageInternal(Message message) throws Exception { // NOSONAR - this.delegate.publish(this.notificationMapper.fromMessage(message)); + protected void handleMessageInternal(Message message) { + try { + this.delegate.publish(this.notificationMapper.fromMessage(message)); + } + catch (Exception e) { + throw new MessageHandlingException(message, "Failed to handle", e); + } } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/CustomObjectNameTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/CustomObjectNameTests.java index d41444b346..5f165cae16 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/CustomObjectNameTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/CustomObjectNameTests.java @@ -119,7 +119,7 @@ public class CustomObjectNameTests { public static class HandlerWithCustomObjectName extends AbstractMessageHandler { @Override - public void handleMessageInternal(Message message) throws Exception { + public void handleMessageInternal(Message message) { } } @@ -153,7 +153,7 @@ public class CustomObjectNameTests { public static class HandlerWithStandardObjectName extends AbstractMessageHandler { @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { } } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/NotificationPublishingChannelAdapterParserTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/NotificationPublishingChannelAdapterParserTests.java index a39539b4dc..54df160cc5 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/NotificationPublishingChannelAdapterParserTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/NotificationPublishingChannelAdapterParserTests.java @@ -180,7 +180,7 @@ public class NotificationPublishingChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingChannelAdapterParserTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingChannelAdapterParserTests.java index 9914189773..8d7e19bcf6 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingChannelAdapterParserTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingChannelAdapterParserTests.java @@ -159,7 +159,7 @@ public class OperationInvokingChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java index d3d9802677..599f9e3189 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/OperationInvokingOutboundGatewayTests.java @@ -163,7 +163,7 @@ public class OperationInvokingOutboundGatewayTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java index 15b5e89e18..083f661aac 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java @@ -318,12 +318,11 @@ public class IdempotentReceiverIntegrationTests { } @Bean - public Advice fooAdvice(final AtomicInteger adviceCalled) { + public Advice fooAdvice(@SuppressWarnings("unused") final AtomicInteger adviceCalled) { return new AbstractRequestHandlerAdvice() { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) - throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled.incrementAndGet(); return callback.execute(); } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/TransformerContextTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/TransformerContextTests.java index 8256231a78..edd0df97d2 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/TransformerContextTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/TransformerContextTests.java @@ -78,7 +78,7 @@ public class TransformerContextTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-jpa/src/test/java/org/springframework/integration/jpa/config/xml/JpaMessageHandlerParserTests.java b/spring-integration-jpa/src/test/java/org/springframework/integration/jpa/config/xml/JpaMessageHandlerParserTests.java index 2d8bc0b40f..b0d9342566 100644 --- a/spring-integration-jpa/src/test/java/org/springframework/integration/jpa/config/xml/JpaMessageHandlerParserTests.java +++ b/spring-integration-jpa/src/test/java/org/springframework/integration/jpa/config/xml/JpaMessageHandlerParserTests.java @@ -227,7 +227,7 @@ public class JpaMessageHandlerParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandler.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandler.java index 3321efbb56..e8c9d1abb4 100644 --- a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandler.java +++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2018 the original author or authors. + * Copyright 2007-2019 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. @@ -115,7 +115,7 @@ public class MongoDbStoringMessageHandler extends AbstractMessageHandler { } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { Assert.isTrue(this.initialized, "This class is not yet initialized. Invoke its afterPropertiesSet() method"); String collectionName = this.collectionNameExpression.getValue(this.evaluationContext, message, String.class); Assert.notNull(collectionName, "'collectionNameExpression' must not evaluate to null"); diff --git a/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/AbstractMqttMessageHandler.java b/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/AbstractMqttMessageHandler.java index 5a853bfb08..bce2d46d60 100644 --- a/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/AbstractMqttMessageHandler.java +++ b/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/AbstractMqttMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -258,7 +258,7 @@ public abstract class AbstractMqttMessageHandler extends AbstractMessageHandler } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { Object mqttMessage = this.converter.fromMessage(message, Object.class); String topic = this.topicProcessor.processMessage(message); if (topic == null && this.defaultTopic == null) { @@ -268,6 +268,6 @@ public abstract class AbstractMqttMessageHandler extends AbstractMessageHandler publish(topic == null ? this.defaultTopic : topic, mqttMessage, message); } - protected abstract void publish(String topic, Object mqttMessage, Message message) throws Exception; + protected abstract void publish(String topic, Object mqttMessage, Message message); } diff --git a/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/MqttPahoMessageHandler.java b/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/MqttPahoMessageHandler.java index afc8b26415..89bf503f55 100644 --- a/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/MqttPahoMessageHandler.java +++ b/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/outbound/MqttPahoMessageHandler.java @@ -31,6 +31,7 @@ import org.springframework.integration.mqtt.event.MqttMessageDeliveredEvent; import org.springframework.integration.mqtt.event.MqttMessageSentEvent; import org.springframework.integration.mqtt.support.MqttMessageConverter; import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHandlingException; import org.springframework.messaging.MessagingException; import org.springframework.util.Assert; @@ -189,17 +190,22 @@ public class MqttPahoMessageHandler extends AbstractMqttMessageHandler } @Override - protected void publish(String topic, Object mqttMessage, Message message) throws Exception { + protected void publish(String topic, Object mqttMessage, Message message) { Assert.isInstanceOf(MqttMessage.class, mqttMessage); - IMqttDeliveryToken token = checkConnection() - .publish(topic, (MqttMessage) mqttMessage); - if (!this.async) { - token.waitForCompletion(this.completionTimeout); + try { + IMqttDeliveryToken token = checkConnection() + .publish(topic, (MqttMessage) mqttMessage); + if (!this.async) { + token.waitForCompletion(this.completionTimeout); + } + else if (this.asyncEvents && this.applicationEventPublisher != null) { + this.applicationEventPublisher.publishEvent( + new MqttMessageSentEvent(this, message, topic, token.getMessageId(), getClientId(), + getClientInstance())); + } } - else if (this.asyncEvents && this.applicationEventPublisher != null) { - this.applicationEventPublisher.publishEvent( - new MqttMessageSentEvent(this, message, topic, token.getMessageId(), getClientId(), - getClientInstance())); + catch (MqttException e) { + throw new MessageHandlingException(message, "Failed to publish to MQTT", e); } } diff --git a/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisQueueOutboundChannelAdapter.java b/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisQueueOutboundChannelAdapter.java index 97fa0c37a4..9bf061774a 100644 --- a/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisQueueOutboundChannelAdapter.java +++ b/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisQueueOutboundChannelAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 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. @@ -108,7 +108,7 @@ public class RedisQueueOutboundChannelAdapter extends AbstractMessageHandler { @Override @SuppressWarnings("unchecked") - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { Object value = message; if (this.extractPayload) { diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java index f56d744210..6ae385d8a7 100644 --- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java +++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java @@ -98,7 +98,7 @@ public class RmiOutboundGatewayParserTests { } @AfterClass - public static void destroyInboundGateway() throws Exception { + public static void destroyInboundGateway() { rmiInboundGateway.destroy(); } @@ -142,7 +142,7 @@ public class RmiOutboundGatewayParserTests { int adviceCalled; @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return callback.execute(); } diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/OutboundChannelAdapterParserTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/OutboundChannelAdapterParserTests.java index e341055ec5..61c23200bd 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/OutboundChannelAdapterParserTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/OutboundChannelAdapterParserTests.java @@ -165,7 +165,7 @@ public class OutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests.java index a555e0204b..6913dd78c1 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests.java @@ -169,7 +169,7 @@ public class SftpOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-test/src/main/java/org/springframework/integration/test/mock/MockMessageHandler.java b/spring-integration-test/src/main/java/org/springframework/integration/test/mock/MockMessageHandler.java index 24c7e132c0..5cc797940b 100644 --- a/spring-integration-test/src/main/java/org/springframework/integration/test/mock/MockMessageHandler.java +++ b/spring-integration-test/src/main/java/org/springframework/integration/test/mock/MockMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public class MockMessageHandler extends AbstractMessageProducingHandler { @SuppressWarnings("unchecked") protected MockMessageHandler(ArgumentCaptor> messageArgumentCaptor) { if (messageArgumentCaptor != null) { - this.capturingMatcher = (CapturingMatcher>) TestUtils.getPropertyValue(messageArgumentCaptor, + this.capturingMatcher = TestUtils.getPropertyValue(messageArgumentCaptor, "capturingMatcher", CapturingMatcher.class); } else { @@ -103,7 +103,7 @@ public class MockMessageHandler extends AbstractMessageProducingHandler { } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { if (this.capturingMatcher != null) { this.capturingMatcher.captureFrom(message); } diff --git a/spring-integration-websocket/src/main/java/org/springframework/integration/websocket/outbound/WebSocketOutboundMessageHandler.java b/spring-integration-websocket/src/main/java/org/springframework/integration/websocket/outbound/WebSocketOutboundMessageHandler.java index 41dcc03447..164e5051ba 100644 --- a/spring-integration-websocket/src/main/java/org/springframework/integration/websocket/outbound/WebSocketOutboundMessageHandler.java +++ b/spring-integration-websocket/src/main/java/org/springframework/integration/websocket/outbound/WebSocketOutboundMessageHandler.java @@ -27,6 +27,7 @@ import org.springframework.integration.websocket.IntegrationWebSocketContainer; import org.springframework.integration.websocket.support.PassThruSubProtocolHandler; import org.springframework.integration.websocket.support.SubProtocolHandlerRegistry; import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHandlingException; import org.springframework.messaging.converter.ByteArrayMessageConverter; import org.springframework.messaging.converter.CompositeMessageConverter; import org.springframework.messaging.converter.DefaultContentTypeResolver; @@ -136,7 +137,7 @@ public class WebSocketOutboundMessageHandler extends AbstractMessageHandler { } @Override - protected void handleMessageInternal(Message message) throws Exception { // NOSONAR + protected void handleMessageInternal(Message message) { String sessionId = null; if (!this.client) { sessionId = this.subProtocolHandlerRegistry.resolveSessionId(message); @@ -166,6 +167,9 @@ public class WebSocketOutboundMessageHandler extends AbstractMessageHandler { logger.error("Exception terminating session id '" + sessionId + "'", secondException); } } + catch (Exception e) { + throw new MessageHandlingException(message, "Failed to handle", e); + } } } diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java index 9180afe8a6..f2ad894516 100644 --- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java +++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java @@ -440,7 +440,7 @@ public class WebServiceOutboundGatewayParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java index f3bf62e426..7a3fb925aa 100644 --- a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java +++ b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 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. @@ -84,56 +84,73 @@ public class ChatMessageSendingMessageHandler extends AbstractXmppConnectionAwar } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { Assert.isTrue(this.initialized, getComponentName() + "#" + this.getComponentType() + " must be initialized"); - Object payload = message.getPayload(); - org.jivesoftware.smack.packet.Message xmppMessage = null; - if (payload instanceof org.jivesoftware.smack.packet.Message) { - xmppMessage = (org.jivesoftware.smack.packet.Message) payload; - } - else { - String to = message.getHeaders().get(XmppHeaders.TO, String.class); - Assert.state(StringUtils.hasText(to), "The '" + XmppHeaders.TO + "' header must not be null"); - xmppMessage = new org.jivesoftware.smack.packet.Message(JidCreate.from(to)); - - if (payload instanceof ExtensionElement) { - xmppMessage.addExtension((ExtensionElement) payload); - } - else if (payload instanceof String) { - if (this.extensionProvider != null) { - String data = (String) payload; - if (!XML_PATTERN.matcher(data.trim()).matches()) { - // Since XMPP Extension parsers deal only with XML content, - // add an arbitrary tag that is removed by the extension parser, - // if the target content isn't XML. - data = "" + data + ""; - } - XmlPullParser xmlPullParser = PacketParserUtils.newXmppParser(new StringReader(data)); - xmlPullParser.next(); - ExtensionElement extension = this.extensionProvider.parse(xmlPullParser); - xmppMessage.addExtension(extension); - } - else { - xmppMessage.setBody((String) payload); - } + try { + Object payload = message.getPayload(); + org.jivesoftware.smack.packet.Message xmppMessage = null; + if (payload instanceof org.jivesoftware.smack.packet.Message) { + xmppMessage = (org.jivesoftware.smack.packet.Message) payload; } else { - throw new MessageHandlingException(message, - "Only payloads of type java.lang.String, org.jivesoftware.smack.packet.Message " + - "or org.jivesoftware.smack.packet.ExtensionElement " + - "are supported. Received [" + payload.getClass().getName() + - "]. Consider adding a Transformer prior to this adapter."); + String to = message.getHeaders().get(XmppHeaders.TO, String.class); + Assert.state(StringUtils.hasText(to), "The '" + XmppHeaders.TO + "' header must not be null"); + xmppMessage = buildXmppMessage(message, payload, to); + } + + if (this.headerMapper != null) { + this.headerMapper.fromHeadersToRequest(message.getHeaders(), xmppMessage); + } + + if (!this.xmppConnection.isConnected() && this.xmppConnection instanceof AbstractXMPPConnection) { + ((AbstractXMPPConnection) this.xmppConnection).connect(); + } + this.xmppConnection.sendStanza(xmppMessage); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new MessageHandlingException(message, "Interrupted", e); + } + catch (Exception e) { + throw new MessageHandlingException(message, "Failed to handle", e); + } + } + + private org.jivesoftware.smack.packet.Message buildXmppMessage(Message message, Object payload, String to) + throws Exception { // NOSONAR Smack throws it + + org.jivesoftware.smack.packet.Message xmppMessage; + xmppMessage = new org.jivesoftware.smack.packet.Message(JidCreate.from(to)); + + if (payload instanceof ExtensionElement) { + xmppMessage.addExtension((ExtensionElement) payload); + } + else if (payload instanceof String) { + if (this.extensionProvider != null) { + String data = (String) payload; + if (!XML_PATTERN.matcher(data.trim()).matches()) { + // Since XMPP Extension parsers deal only with XML content, + // add an arbitrary tag that is removed by the extension parser, + // if the target content isn't XML. + data = "" + data + ""; + } + XmlPullParser xmlPullParser = PacketParserUtils.newXmppParser(new StringReader(data)); + xmlPullParser.next(); + ExtensionElement extension = this.extensionProvider.parse(xmlPullParser); + xmppMessage.addExtension(extension); + } + else { + xmppMessage.setBody((String) payload); } } - - if (this.headerMapper != null) { - this.headerMapper.fromHeadersToRequest(message.getHeaders(), xmppMessage); + else { + throw new MessageHandlingException(message, + "Only payloads of type java.lang.String, org.jivesoftware.smack.packet.Message " + + "or org.jivesoftware.smack.packet.ExtensionElement " + + "are supported. Received [" + payload.getClass().getName() + + "]. Consider adding a Transformer prior to this adapter."); } - - if (!this.xmppConnection.isConnected() && this.xmppConnection instanceof AbstractXMPPConnection) { - ((AbstractXMPPConnection) this.xmppConnection).connect(); - } - this.xmppConnection.sendStanza(xmppMessage); + return xmppMessage; } } diff --git a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/PresenceSendingMessageHandler.java b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/PresenceSendingMessageHandler.java index f2e8334e38..35d4a2339d 100644 --- a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/PresenceSendingMessageHandler.java +++ b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/PresenceSendingMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 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.jivesoftware.smack.packet.Presence; import org.springframework.integration.xmpp.core.AbstractXmppConnectionAwareMessageHandler; import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHandlingException; import org.springframework.util.Assert; /** @@ -48,15 +49,24 @@ public class PresenceSendingMessageHandler extends AbstractXmppConnectionAwareMe } @Override - protected void handleMessageInternal(Message message) throws Exception { + protected void handleMessageInternal(Message message) { Assert.state(this.initialized, this.getComponentName() + " must be initialized"); Object payload = message.getPayload(); Assert.state(payload instanceof Presence, "Payload must be of type 'org.jivesoftware.smack.packet.Presence', was: " + payload.getClass().getName()); - if (!this.xmppConnection.isConnected() && this.xmppConnection instanceof AbstractXMPPConnection) { - ((AbstractXMPPConnection) this.xmppConnection).connect(); + try { + if (!this.xmppConnection.isConnected() && this.xmppConnection instanceof AbstractXMPPConnection) { + ((AbstractXMPPConnection) this.xmppConnection).connect(); + } + this.xmppConnection.sendStanza((Presence) payload); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new MessageHandlingException(message, "Interrupted", e); + } + catch (Exception e) { + throw new MessageHandlingException(message, "Failed to handle", e); } - this.xmppConnection.sendStanza((Presence) payload); } } diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java index b5df64099a..2905965d1e 100644 --- a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java @@ -161,7 +161,7 @@ public class ChatMessageOutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/PresenceOutboundChannelAdapterParserTests.java b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/PresenceOutboundChannelAdapterParserTests.java index 4f22b0b40c..fd835ea746 100644 --- a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/PresenceOutboundChannelAdapterParserTests.java +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/PresenceOutboundChannelAdapterParserTests.java @@ -95,7 +95,7 @@ public class PresenceOutboundChannelAdapterParserTests { public static class FooAdvice extends AbstractRequestHandlerAdvice { @Override - protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) { adviceCalled++; return null; } diff --git a/src/reference/asciidoc/handler-advice.adoc b/src/reference/asciidoc/handler-advice.adoc index 803d7e5c60..ff63cdc0ee 100644 --- a/src/reference/asciidoc/handler-advice.adoc +++ b/src/reference/asciidoc/handler-advice.adoc @@ -327,6 +327,8 @@ When `true`, it traverses exception causes until it finds a match or runs out of To use this classifier for retry, use a `SimpleRetryPolicy` created with the constructor that takes the max attempts, the `Map` of `Exception` objects, and the `traverseCauses` boolean. Then you can inject this policy into the `RetryTemplate`. +IMPORTANT: `traverseCauses` is required in this case because user exceptions may be wrapped in a `MessagingException`. + [[circuit-breaker-advice]] ===== Circuit Breaker Advice