diff --git a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsAdapterParserUtils.java b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsAdapterParserUtils.java index 4ecc7bd005..c3a97cc830 100644 --- a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsAdapterParserUtils.java +++ b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsAdapterParserUtils.java @@ -16,11 +16,9 @@ package org.springframework.integration.jms.config; -import javax.jms.Session; - import org.w3c.dom.Element; -import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; /** @@ -28,7 +26,7 @@ import org.springframework.util.StringUtils; * * @author Mark Fisher */ -public abstract class JmsAdapterParserUtils { +abstract class JmsAdapterParserUtils { static final String JMS_TEMPLATE_ATTRIBUTE = "jms-template"; @@ -50,35 +48,48 @@ public abstract class JmsAdapterParserUtils { static final String HEADER_MAPPER_PROPERTY = "headerMapper"; + /* + * The following constants match those of javax.jms.Session. + * They are duplicated here to avoid a dependency in tooling. + */ - public static String determineConnectionFactoryBeanName(Element element) { + static final int SESSION_TRANSACTED = 0; + + private static final int AUTO_ACKNOWLEDGE = 1; + + private static final int CLIENT_ACKNOWLEDGE = 2; + + private static final int DUPS_OK_ACKNOWLEDGE = 3; + + + static String determineConnectionFactoryBeanName(Element element, ParserContext parserContext) { String connectionFactoryBeanName = "connectionFactory"; if (element.hasAttribute(CONNECTION_FACTORY_ATTRIBUTE)) { connectionFactoryBeanName = element.getAttribute(CONNECTION_FACTORY_ATTRIBUTE); if (!StringUtils.hasText(connectionFactoryBeanName)) { - throw new BeanCreationException( - "JMS adapter 'connection-factory' attribute must not be empty"); + parserContext.getReaderContext().error( + "JMS adapter 'connection-factory' attribute must not be empty", element); } } return connectionFactoryBeanName; } - public static Integer parseAcknowledgeMode(Element element) { + static Integer parseAcknowledgeMode(Element element, ParserContext parserContext) { String acknowledge = element.getAttribute("acknowledge"); if (StringUtils.hasText(acknowledge)) { - int acknowledgeMode = Session.AUTO_ACKNOWLEDGE; + int acknowledgeMode = AUTO_ACKNOWLEDGE; if ("transacted".equals(acknowledge)) { - acknowledgeMode = Session.SESSION_TRANSACTED; + acknowledgeMode = SESSION_TRANSACTED; } else if ("dups-ok".equals(acknowledge)) { - acknowledgeMode = Session.DUPS_OK_ACKNOWLEDGE; + acknowledgeMode = DUPS_OK_ACKNOWLEDGE; } else if ("client".equals(acknowledge)) { - acknowledgeMode = Session.CLIENT_ACKNOWLEDGE; + acknowledgeMode = CLIENT_ACKNOWLEDGE; } else if (!"auto".equals(acknowledge)) { - throw new BeanCreationException("Invalid JMS 'acknowledge' setting: " + - "only \"auto\", \"client\", \"dups-ok\" and \"transacted\" supported."); + parserContext.getReaderContext().error("Invalid JMS 'acknowledge' setting: " + + "only \"auto\", \"client\", \"dups-ok\" and \"transacted\" supported.", element); } return acknowledgeMode; } diff --git a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java index b4938773f7..82970d0ceb 100644 --- a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java +++ b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsInboundChannelAdapterParser.java @@ -24,7 +24,6 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; -import org.springframework.integration.jms.JmsDestinationPollingSource; import org.springframework.util.StringUtils; /** @@ -44,7 +43,8 @@ public class JmsInboundChannelAdapterParser extends AbstractPollingInboundChanne @Override protected String parseSource(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(JmsDestinationPollingSource.class); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( + "org.springframework.integration.jms.JmsDestinationPollingSource"); String jmsTemplate = element.getAttribute(JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE); String destination = element.getAttribute(JmsAdapterParserUtils.DESTINATION_ATTRIBUTE); String destinationName = element.getAttribute(JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE); @@ -62,7 +62,7 @@ public class JmsInboundChannelAdapterParser extends AbstractPollingInboundChanne builder.addConstructorArgReference(jmsTemplate); } else if (StringUtils.hasText(destination) || StringUtils.hasText(destinationName)) { - builder.addConstructorArgReference(JmsAdapterParserUtils.determineConnectionFactoryBeanName(element)); + builder.addConstructorArgReference(JmsAdapterParserUtils.determineConnectionFactoryBeanName(element, parserContext)); if (StringUtils.hasText(destination)) { builder.addConstructorArgReference(destination); } diff --git a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsMessageDrivenEndpointParser.java b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsMessageDrivenEndpointParser.java index 96c6ba8c4c..7d05843724 100644 --- a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsMessageDrivenEndpointParser.java +++ b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsMessageDrivenEndpointParser.java @@ -16,8 +16,6 @@ package org.springframework.integration.jms.config; -import javax.jms.Session; - import org.w3c.dom.Element; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -25,10 +23,6 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; -import org.springframework.integration.jms.ChannelPublishingJmsMessageListener; -import org.springframework.integration.jms.JmsMessageDrivenEndpoint; -import org.springframework.jms.listener.DefaultMessageListenerContainer; -import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -58,8 +52,8 @@ public class JmsMessageDrivenEndpointParser extends AbstractSingleBeanDefinition @Override - protected Class getBeanClass(Element element) { - return JmsMessageDrivenEndpoint.class; + protected String getBeanClassName(Element element) { + return "org.springframework.integration.jms.JmsMessageDrivenEndpoint"; } @Override @@ -84,30 +78,35 @@ public class JmsMessageDrivenEndpointParser extends AbstractSingleBeanDefinition private String parseMessageListenerContainer(Element element, ParserContext parserContext) { if (element.hasAttribute("container")) { for (String containerAttribute : containerAttributes) { - Assert.isTrue(!element.hasAttribute(containerAttribute), "The '" + containerAttribute + - "' attribute should not be provided when specifying a 'container' reference."); + if (element.hasAttribute(containerAttribute)) { + parserContext.getReaderContext().error("The '" + containerAttribute + + "' attribute should not be provided when specifying a 'container' reference.", element); + } } return element.getAttribute("container"); } // otherwise, we build a DefaultMessageListenerContainer instance - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(DefaultMessageListenerContainer.class); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( + "org.springframework.jms.listener.DefaultMessageListenerContainer"); String destinationAttribute = this.expectReply ? "request-destination" : "destination"; String destinationNameAttribute = this.expectReply ? "request-destination-name" : "destination-name"; String destination = element.getAttribute(destinationAttribute); String destinationName = element.getAttribute(destinationNameAttribute); - Assert.isTrue(StringUtils.hasText(destination) ^ StringUtils.hasText(destinationName), - "Exactly one of '" + destinationAttribute + "' or '" + destinationNameAttribute + "' is required."); + if (!(StringUtils.hasText(destination) ^ StringUtils.hasText(destinationName))) { + parserContext.getReaderContext().error( + "Exactly one of '" + destinationAttribute + "' or '" + destinationNameAttribute + "' is required.", element); + } builder.addPropertyReference(JmsAdapterParserUtils.CONNECTION_FACTORY_PROPERTY, - JmsAdapterParserUtils.determineConnectionFactoryBeanName(element)); + JmsAdapterParserUtils.determineConnectionFactoryBeanName(element, parserContext)); if (StringUtils.hasText(destination)) { builder.addPropertyReference("destination", destination); } else { builder.addPropertyValue("destinationName", destinationName); } - Integer acknowledgeMode = JmsAdapterParserUtils.parseAcknowledgeMode(element); + Integer acknowledgeMode = JmsAdapterParserUtils.parseAcknowledgeMode(element, parserContext); if (acknowledgeMode != null) { - if (acknowledgeMode.intValue() == Session.SESSION_TRANSACTED) { + if (acknowledgeMode.intValue() == JmsAdapterParserUtils.SESSION_TRANSACTED) { builder.addPropertyValue("sessionTransacted", Boolean.TRUE); } else { @@ -126,7 +125,8 @@ public class JmsMessageDrivenEndpointParser extends AbstractSingleBeanDefinition } private String parseMessageListener(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ChannelPublishingJmsMessageListener.class); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( + "org.springframework.integration.jms.ChannelPublishingJmsMessageListener"); builder.addPropertyValue("expectReply", this.expectReply); if (this.expectReply) { IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "request-channel"); diff --git a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java index 5a629137bd..8eaa110000 100644 --- a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java +++ b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParser.java @@ -24,7 +24,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; -import org.springframework.integration.jms.JmsSendingMessageHandler; import org.springframework.util.StringUtils; /** @@ -36,7 +35,8 @@ public class JmsOutboundChannelAdapterParser extends AbstractOutboundChannelAdap @Override protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(JmsSendingMessageHandler.class); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( + "org.springframework.integration.jms.JmsSendingMessageHandler"); String jmsTemplate = element.getAttribute(JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE); String destination = element.getAttribute(JmsAdapterParserUtils.DESTINATION_ATTRIBUTE); String destinationName = element.getAttribute(JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE); @@ -52,7 +52,7 @@ public class JmsOutboundChannelAdapterParser extends AbstractOutboundChannelAdap } else if (StringUtils.hasText(destination) ^ StringUtils.hasText(destinationName)) { builder.addPropertyReference(JmsAdapterParserUtils.CONNECTION_FACTORY_PROPERTY, - JmsAdapterParserUtils.determineConnectionFactoryBeanName(element)); + JmsAdapterParserUtils.determineConnectionFactoryBeanName(element, parserContext)); if (StringUtils.hasText(destination)) { builder.addPropertyReference(JmsAdapterParserUtils.DESTINATION_PROPERTY, destination); } diff --git a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java index ea1b50e833..dc6515b2f4 100644 --- a/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java +++ b/org.springframework.integration.jms/src/main/java/org/springframework/integration/jms/config/JmsOutboundGatewayParser.java @@ -22,8 +22,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.AbstractConsumerEndpointParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; -import org.springframework.integration.jms.JmsOutboundGateway; -import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -40,12 +38,15 @@ public class JmsOutboundGatewayParser extends AbstractConsumerEndpointParser { @Override protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(JmsOutboundGateway.class); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( + "org.springframework.integration.jms.JmsOutboundGateway"); builder.addPropertyReference("connectionFactory", element.getAttribute("connection-factory")); String requestDestination = element.getAttribute("request-destination"); String requestDestinationName = element.getAttribute("request-destination-name"); - Assert.isTrue(StringUtils.hasText(requestDestination) ^ StringUtils.hasText(requestDestinationName), - "Exactly one of the 'request-destination' or 'request-destination-name' attributes is required."); + if (!(StringUtils.hasText(requestDestination) ^ StringUtils.hasText(requestDestinationName))) { + parserContext.getReaderContext().error( + "Exactly one of the 'request-destination' or 'request-destination-name' attributes is required.", element); + } if (StringUtils.hasText(requestDestination)) { builder.addPropertyReference("requestDestination", requestDestination); } diff --git a/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsInboundGatewayParserTests.java b/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsInboundGatewayParserTests.java index 11e83375c7..cc1e852be8 100644 --- a/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsInboundGatewayParserTests.java +++ b/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsInboundGatewayParserTests.java @@ -19,11 +19,11 @@ package org.springframework.integration.jms.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; -import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.channel.PollableChannel; @@ -134,8 +134,9 @@ public class JmsInboundGatewayParserTests { try { new ClassPathXmlApplicationContext("jmsGatewayWithConnectionFactoryOnly.xml", this.getClass()); } - catch (RuntimeException e) { - assertEquals(IllegalArgumentException.class, e.getCause().getClass()); + catch (BeanDefinitionStoreException e) { + assertTrue(e.getMessage().contains("request-destination")); + assertTrue(e.getMessage().contains("request-destination-name")); throw e; } } @@ -145,8 +146,8 @@ public class JmsInboundGatewayParserTests { try { new ClassPathXmlApplicationContext("jmsGatewayWithEmptyConnectionFactory.xml", this.getClass()); } - catch (RuntimeException e) { - assertEquals(BeanCreationException.class, e.getCause().getClass()); + catch (BeanDefinitionStoreException e) { + assertTrue(e.getMessage().contains("connection-factory")); throw e; } } diff --git a/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java b/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java index 306e8902d9..faee14af00 100644 --- a/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java +++ b/org.springframework.integration.jms/src/test/java/org/springframework/integration/jms/config/JmsOutboundChannelAdapterParserTests.java @@ -18,11 +18,11 @@ package org.springframework.integration.jms.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; -import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.endpoint.EventDrivenConsumer; @@ -80,8 +80,8 @@ public class JmsOutboundChannelAdapterParserTests { try { new ClassPathXmlApplicationContext("jmsOutboundWithEmptyConnectionFactory.xml", this.getClass()); } - catch (RuntimeException e) { - assertEquals(BeanCreationException.class, e.getCause().getClass()); + catch (BeanDefinitionStoreException e) { + assertTrue(e.getMessage().contains("connection-factory")); throw e; } }