diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java index d1f2b633d4..61fa5accac 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java @@ -19,19 +19,16 @@ package org.springframework.boot.autoconfigure.jms.activemq; import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.transport.vm.VMTransportFactory; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; +import org.springframework.boot.autoconfigure.jta.JtaAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.core.type.AnnotatedTypeMetadata; /** * {@link EnableAutoConfiguration Auto-configuration} to integrate with an ActiveMQ @@ -39,67 +36,16 @@ import org.springframework.core.type.AnnotatedTypeMetadata; * embedded broker. * * @author Stephane Nicoll + * @author Phillip Webb * @since 1.1.0 */ @Configuration @AutoConfigureBefore(JmsAutoConfiguration.class) +@AutoConfigureAfter(JtaAutoConfiguration.class) @ConditionalOnClass({ ConnectionFactory.class, ActiveMQConnectionFactory.class }) @ConditionalOnMissingBean(ConnectionFactory.class) +@EnableConfigurationProperties(ActiveMQProperties.class) +@Import({ ActiveMQXAConnectionFactoryConfiguration.class, ActiveMQConnectionFactoryConfiguration.class }) public class ActiveMQAutoConfiguration { - @Configuration - @ConditionalOnClass(VMTransportFactory.class) - @Conditional(EmbeddedBrokerCondition.class) - @Import(ActiveMQConnectionFactoryConfiguration.class) - protected static class EmbeddedBroker { - } - - @Configuration - @Conditional(NonEmbeddedBrokerCondition.class) - @Import(ActiveMQConnectionFactoryConfiguration.class) - protected static class NetworkBroker { - } - - static abstract class BrokerTypeCondition extends SpringBootCondition { - private final boolean embedded; - - BrokerTypeCondition(boolean embedded) { - this.embedded = embedded; - } - - @Override - public ConditionOutcome getMatchOutcome(ConditionContext context, - AnnotatedTypeMetadata metadata) { - String brokerUrl = ActiveMQProperties.determineBrokerUrl(context - .getEnvironment()); - boolean match = brokerUrl.contains("vm://"); - boolean outcome = (match == this.embedded); - return new ConditionOutcome(outcome, buildMessage(brokerUrl, outcome)); - } - - protected String buildMessage(String brokerUrl, boolean outcome) { - String brokerType = this.embedded ? "Embedded" : "Network"; - String detected = outcome ? "detected" : "not detected"; - return brokerType + " ActiveMQ broker " + detected + " - brokerUrl '" - + brokerUrl + "'"; - } - - } - - static class EmbeddedBrokerCondition extends BrokerTypeCondition { - - EmbeddedBrokerCondition() { - super(true); - } - - } - - static class NonEmbeddedBrokerCondition extends BrokerTypeCondition { - - NonEmbeddedBrokerCondition() { - super(false); - } - - } - } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java index 65006e61c3..8e2c4ff9b4 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java @@ -18,27 +18,34 @@ package org.springframework.boot.autoconfigure.jms.activemq; import javax.jms.ConnectionFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.pool.PooledConnectionFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** - * Creates a {@link ConnectionFactory} based on {@link ActiveMQProperties}. + * Configuration for ActiveMQ {@link ConnectionFactory}. * * @author Greg Turnquist * @author Stephane Nicoll + * @author Phillip Webb * @since 1.1.0 */ @Configuration -@EnableConfigurationProperties(ActiveMQProperties.class) +@ConditionalOnMissingBean(ConnectionFactory.class) class ActiveMQConnectionFactoryConfiguration { - @Autowired - private ActiveMQProperties properties; - @Bean - public ConnectionFactory jmsConnectionFactory() { - return this.properties.createConnectionFactory(); + public ConnectionFactory jmsConnectionFactory(ActiveMQProperties properties) { + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactoryFactory( + properties).createConnectionFactory(ActiveMQConnectionFactory.class); + if (properties.isPooled()) { + PooledConnectionFactory pool = new PooledConnectionFactory(); + pool.setConnectionFactory(connectionFactory); + return pool; + } + return connectionFactory; } + } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryFactory.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryFactory.java new file mode 100644 index 0000000000..6d3f82074b --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryFactory.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jms.activemq; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Factory to create a {@link ActiveMQConnectionFactory} instance from properties defined + * in {@link ActiveMQProperties}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +class ActiveMQConnectionFactoryFactory { + + private static final String DEFAULT_EMBEDDED_BROKER_URL = "vm://localhost?broker.persistent=false"; + + private static final String DEFAULT_NETWORK_BROKER_URL = "tcp://localhost:61616"; + + private final ActiveMQProperties properties; + + public ActiveMQConnectionFactoryFactory(ActiveMQProperties properties) { + Assert.notNull(properties, "Properties must not be null"); + this.properties = properties; + } + + public T createConnectionFactory( + Class factoryClass) { + try { + return doCreateConnectionFactory(factoryClass); + } + catch (Exception ex) { + throw new IllegalStateException("Unable to create " + + "ActiveMQConnectionFactory", ex); + } + } + + private T doCreateConnectionFactory( + Class factoryClass) throws Exception { + String brokerUrl = determineBrokerUrl(); + String user = this.properties.getUser(); + String password = this.properties.getPassword(); + if (StringUtils.hasLength(user) && StringUtils.hasLength(password)) { + return factoryClass.getConstructor(String.class, String.class, String.class) + .newInstance(user, password, brokerUrl); + } + return factoryClass.getConstructor(String.class).newInstance(brokerUrl); + } + + String determineBrokerUrl() { + if (this.properties.getBrokerUrl() != null) { + return this.properties.getBrokerUrl(); + } + if (this.properties.isInMemory()) { + return DEFAULT_EMBEDDED_BROKER_URL; + } + return DEFAULT_NETWORK_BROKER_URL; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java index de3db1caf2..0709c08668 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java @@ -16,15 +16,7 @@ package org.springframework.boot.autoconfigure.jms.activemq; -import javax.jms.ConnectionFactory; - -import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.pool.PooledConnectionFactory; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.env.Environment; -import org.springframework.core.env.PropertyResolver; -import org.springframework.util.StringUtils; /** * Configuration properties for ActiveMQ @@ -35,10 +27,6 @@ import org.springframework.util.StringUtils; @ConfigurationProperties(prefix = "spring.activemq") public class ActiveMQProperties { - public static final String DEFAULT_EMBEDDED_BROKER_URL = "vm://localhost?broker.persistent=false"; - - public static final String DEFAULT_NETWORK_BROKER_URL = "tcp://localhost:61616"; - private String brokerUrl; private boolean inMemory = true; @@ -93,52 +81,4 @@ public class ActiveMQProperties { this.password = password; } - /** - * Return a new {@link ConnectionFactory} from these properties. - */ - public ConnectionFactory createConnectionFactory() { - ConnectionFactory connectionFactory = createActiveMQConnectionFactory(); - if (isPooled()) { - PooledConnectionFactory pool = new PooledConnectionFactory(); - pool.setConnectionFactory(connectionFactory); - return pool; - } - return connectionFactory; - } - - private ConnectionFactory createActiveMQConnectionFactory() { - String brokerUrl = determineBrokerUrl(); - if (StringUtils.hasLength(this.user) && StringUtils.hasLength(this.password)) { - return new ActiveMQConnectionFactory(this.user, this.password, brokerUrl); - } - return new ActiveMQConnectionFactory(brokerUrl); - } - - String determineBrokerUrl() { - return determineBrokerUrl(this.brokerUrl, this.inMemory); - } - - /** - * Determine the broker url to use for the specified {@link Environment}. If no broker - * url is specified through configuration, a default broker is provided, that is - * {@value #DEFAULT_EMBEDDED_BROKER_URL} if the {@code inMemory} flag is {@code null} - * or {@code true}, {@value #DEFAULT_NETWORK_BROKER_URL} otherwise. - * @param environment the environment to extract configuration from - * @return the broker url to use - */ - public static String determineBrokerUrl(Environment environment) { - PropertyResolver resolver = new RelaxedPropertyResolver(environment, - "spring.activemq."); - String brokerUrl = resolver.getProperty("brokerUrl"); - Boolean inMemory = resolver.getProperty("inMemory", Boolean.class); - return determineBrokerUrl(brokerUrl, inMemory); - } - - private static String determineBrokerUrl(String brokerUrl, Boolean inMemory) { - if (brokerUrl != null) { - return brokerUrl; - } - boolean embedded = inMemory == null || inMemory; - return (embedded ? DEFAULT_EMBEDDED_BROKER_URL : DEFAULT_NETWORK_BROKER_URL); - } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQXAConnectionFactoryConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQXAConnectionFactoryConfiguration.java new file mode 100644 index 0000000000..a30fd80e61 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQXAConnectionFactoryConfiguration.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jms.activemq; + +import javax.jms.ConnectionFactory; +import javax.transaction.TransactionManager; + +import org.apache.activemq.ActiveMQXAConnectionFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.jta.XAConnectionFactoryWrapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for ActiveMQ XA {@link ConnectionFactory}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +@Configuration +@ConditionalOnClass(TransactionManager.class) +@ConditionalOnBean(XAConnectionFactoryWrapper.class) +@ConditionalOnMissingBean(ConnectionFactory.class) +class ActiveMQXAConnectionFactoryConfiguration { + + @Bean + public ConnectionFactory jmsConnectionFactory(ActiveMQProperties properties, + XAConnectionFactoryWrapper wrapper) throws Exception { + ActiveMQXAConnectionFactory connectionFactory = new ActiveMQConnectionFactoryFactory( + properties).createConnectionFactory(ActiveMQXAConnectionFactory.class); + return wrapper.wrapConnectionFactory(connectionFactory); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfiguration.java index 7db9103fa3..8e86dea97a 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfiguration.java @@ -16,48 +16,25 @@ package org.springframework.boot.autoconfigure.jms.hornetq; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import javax.jms.ConnectionFactory; -import org.hornetq.api.core.TransportConfiguration; -import org.hornetq.api.core.client.HornetQClient; -import org.hornetq.api.core.client.ServerLocator; import org.hornetq.api.jms.HornetQJMSClient; -import org.hornetq.api.jms.JMSFactoryType; -import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory; -import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory; -import org.hornetq.core.remoting.impl.netty.TransportConstants; -import org.hornetq.jms.client.HornetQConnectionFactory; -import org.hornetq.jms.server.config.JMSConfiguration; -import org.hornetq.jms.server.config.JMSQueueConfiguration; -import org.hornetq.jms.server.config.TopicConfiguration; -import org.hornetq.jms.server.config.impl.JMSConfigurationImpl; -import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl; -import org.hornetq.jms.server.config.impl.TopicConfigurationImpl; -import org.hornetq.jms.server.embedded.EmbeddedJMS; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.util.ClassUtils; +import org.springframework.context.annotation.Import; /** - * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration - * Auto-configuration} to integrate with an HornetQ broker. If the necessary classes are - * present, embed the broker in the application by default. Otherwise, connect to a broker - * available on the local machine with the default settings. + * {@link EnableAutoConfiguration Auto-configuration} to integrate with an HornetQ broker. + * If the necessary classes are present, embed the broker in the application by default. + * Otherwise, connect to a broker available on the local machine with the default + * settings. * * @author Stephane Nicoll + * @author Phillip Webb * @since 1.1.0 * @see HornetQProperties */ @@ -65,151 +42,9 @@ import org.springframework.util.ClassUtils; @AutoConfigureBefore(JmsAutoConfiguration.class) @ConditionalOnClass({ ConnectionFactory.class, HornetQJMSClient.class }) @EnableConfigurationProperties(HornetQProperties.class) +@Import({ HornetQEmbeddedServerConfiguration.class, + HornetQXAConnectionFactoryConfiguration.class, + HornetQConnectionFactoryConfiguration.class }) public class HornetQAutoConfiguration { - private static final String EMBEDDED_JMS_CLASS = "org.hornetq.jms.server.embedded.EmbeddedJMS"; - - @Autowired - private HornetQProperties properties; - - /** - * Create the {@link ConnectionFactory} to use if none is provided. If no - * {@linkplain HornetQProperties#getMode() mode} has been explicitly set, start an - * embedded server unless it has been explicitly disabled, connect to a broker - * available on the local machine with the default settings otherwise. - */ - @Bean - @ConditionalOnMissingBean - public ConnectionFactory jmsConnectionFactory() { - HornetQMode mode = this.properties.getMode(); - if (mode == null) { - mode = deduceMode(); - } - if (mode == HornetQMode.EMBEDDED) { - return createEmbeddedConnectionFactory(); - } - return createNativeConnectionFactory(); - } - - /** - * Deduce the {@link HornetQMode} to use if none has been set. - */ - private HornetQMode deduceMode() { - if (this.properties.getEmbedded().isEnabled() - && ClassUtils.isPresent(EMBEDDED_JMS_CLASS, null)) { - return HornetQMode.EMBEDDED; - } - return HornetQMode.NATIVE; - } - - private ConnectionFactory createEmbeddedConnectionFactory() { - try { - TransportConfiguration transportConfiguration = new TransportConfiguration( - InVMConnectorFactory.class.getName(), this.properties.getEmbedded() - .generateTransportParameters()); - ServerLocator serviceLocator = HornetQClient - .createServerLocatorWithoutHA(transportConfiguration); - return new HornetQConnectionFactory(serviceLocator); - } - catch (NoClassDefFoundError ex) { - throw new IllegalStateException("Unable to create InVM " - + "HornetQ connection, ensure that hornet-jms-server.jar " - + "is in the classpath", ex); - } - } - - private ConnectionFactory createNativeConnectionFactory() { - Map params = new HashMap(); - params.put(TransportConstants.HOST_PROP_NAME, this.properties.getHost()); - params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort()); - TransportConfiguration transportConfiguration = new TransportConfiguration( - NettyConnectorFactory.class.getName(), params); - return HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, - transportConfiguration); - } - - /** - * Configuration used to create the embedded HornetQ server. - */ - @Configuration - @ConditionalOnClass(name = EMBEDDED_JMS_CLASS) - @ConditionalOnExpression("${spring.hornetq.embedded.enabled:true}") - static class EmbeddedServerConfiguration { - - @Autowired - private HornetQProperties properties; - - @Autowired(required = false) - private List configurationCustomizers; - - @Autowired(required = false) - private List queuesConfiguration; - - @Autowired(required = false) - private List topicsConfiguration; - - @Bean - @ConditionalOnMissingBean - public org.hornetq.core.config.Configuration hornetQConfiguration() { - return new HornetQEmbeddedConfigurationFactory(this.properties) - .createConfiguration(); - } - - @Bean(initMethod = "start", destroyMethod = "stop") - @ConditionalOnMissingBean - public EmbeddedJMS hornetQServer( - org.hornetq.core.config.Configuration configuration, - JMSConfiguration jmsConfiguration) { - EmbeddedJMS server = new EmbeddedJMS(); - customize(configuration); - server.setConfiguration(configuration); - server.setJmsConfiguration(jmsConfiguration); - server.setRegistry(new HornetQNoOpBindingRegistry()); - return server; - } - - private void customize(org.hornetq.core.config.Configuration configuration) { - if (this.configurationCustomizers != null) { - AnnotationAwareOrderComparator.sort(this.configurationCustomizers); - for (HornetQConfigurationCustomizer customizer : this.configurationCustomizers) { - customizer.customize(configuration); - } - } - } - - @Bean - @ConditionalOnMissingBean - public JMSConfiguration hornetQJmsConfiguration() { - JMSConfiguration configuration = new JMSConfigurationImpl(); - addAll(configuration.getQueueConfigurations(), this.queuesConfiguration); - addAll(configuration.getTopicConfigurations(), this.topicsConfiguration); - addQueues(configuration, this.properties.getEmbedded().getQueues()); - addTopics(configuration, this.properties.getEmbedded().getTopics()); - return configuration; - } - - private void addAll(List list, Collection items) { - if (items != null) { - list.addAll(items); - } - } - - private void addQueues(JMSConfiguration configuration, String[] queues) { - boolean persistent = this.properties.getEmbedded().isPersistent(); - for (String queue : queues) { - configuration.getQueueConfigurations().add( - new JMSQueueConfigurationImpl(queue, null, persistent, "/queue/" - + queue)); - } - } - - private void addTopics(JMSConfiguration configuration, String[] topics) { - for (String topic : topics) { - configuration.getTopicConfigurations().add( - new TopicConfigurationImpl(topic, "/topic/" + topic)); - } - } - - } - } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryConfiguration.java new file mode 100644 index 0000000000..64e361c30d --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryConfiguration.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jms.hornetq; + +import javax.jms.ConnectionFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hornetq.jms.client.HornetQConnectionFactory; +import org.hornetq.jms.server.embedded.EmbeddedJMS; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for HornetQ {@link ConnectionFactory}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +@Configuration +@ConditionalOnMissingBean(ConnectionFactory.class) +class HornetQConnectionFactoryConfiguration { + + private static Log logger = LogFactory + .getLog(HornetQEmbeddedServerConfiguration.class); + + // Ensure JMS is setup before XA + @Autowired(required = false) + private EmbeddedJMS embeddedJMS; + + @Bean + public ConnectionFactory jmsConnectionFactory(HornetQProperties properties) { + if (this.embeddedJMS != null && logger.isDebugEnabled()) { + logger.debug("Using embdedded HornetQ broker"); + } + return new HornetQConnectionFactoryFactory(properties) + .createConnectionFactory(HornetQConnectionFactory.class); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryFactory.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryFactory.java new file mode 100644 index 0000000000..496c73536a --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryFactory.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jms.hornetq; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + +import org.hornetq.api.core.TransportConfiguration; +import org.hornetq.api.core.client.HornetQClient; +import org.hornetq.api.core.client.ServerLocator; +import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory; +import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory; +import org.hornetq.core.remoting.impl.netty.TransportConstants; +import org.hornetq.jms.client.HornetQConnectionFactory; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +/** + * Factory to create a {@link HornetQConnectionFactory} instance from properties defined + * in {@link HornetQProperties}. + * + * @author Phillip Webb + * @author Stephane Nicoll + * @since 1.2.0 + */ +class HornetQConnectionFactoryFactory { + + static final String EMBEDDED_JMS_CLASS = "org.hornetq.jms.server.embedded.EmbeddedJMS"; + + private final HornetQProperties properties; + + public HornetQConnectionFactoryFactory(HornetQProperties properties) { + Assert.notNull(properties, "Properties must not be null"); + this.properties = properties; + } + + public T createConnectionFactory( + Class factoryClass) { + try { + return doCreateConnectionFactory(factoryClass); + } + catch (Exception ex) { + throw new IllegalStateException("Unable to create " + + "HornetQConnectionFactory", ex); + } + } + + private T doCreateConnectionFactory( + Class factoryClass) throws Exception { + HornetQMode mode = this.properties.getMode(); + if (mode == null) { + mode = deduceMode(); + } + if (mode == HornetQMode.EMBEDDED) { + return createEmbeddedConnectionFactory(factoryClass); + } + return createNativeConnectionFactory(factoryClass); + } + + /** + * Deduce the {@link HornetQMode} to use if none has been set. + */ + private HornetQMode deduceMode() { + if (this.properties.getEmbedded().isEnabled() + && ClassUtils.isPresent(EMBEDDED_JMS_CLASS, null)) { + return HornetQMode.EMBEDDED; + } + return HornetQMode.NATIVE; + } + + private T createEmbeddedConnectionFactory( + Class factoryClass) throws Exception { + try { + TransportConfiguration transportConfiguration = new TransportConfiguration( + InVMConnectorFactory.class.getName(), this.properties.getEmbedded() + .generateTransportParameters()); + ServerLocator serviceLocator = HornetQClient + .createServerLocatorWithoutHA(transportConfiguration); + return factoryClass.getConstructor(ServerLocator.class).newInstance( + serviceLocator); + } + catch (NoClassDefFoundError ex) { + throw new IllegalStateException("Unable to create InVM " + + "HornetQ connection, ensure that hornet-jms-server.jar " + + "is in the classpath", ex); + } + } + + private T createNativeConnectionFactory( + Class factoryClass) throws Exception { + Map params = new HashMap(); + params.put(TransportConstants.HOST_PROP_NAME, this.properties.getHost()); + params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort()); + TransportConfiguration transportConfiguration = new TransportConfiguration( + NettyConnectorFactory.class.getName(), params); + Constructor constructor = factoryClass.getConstructor(boolean.class, + TransportConfiguration[].class); + return constructor.newInstance(false, + new TransportConfiguration[] { transportConfiguration }); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQEmbeddedServerConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQEmbeddedServerConfiguration.java new file mode 100644 index 0000000000..2a82e9b1df --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQEmbeddedServerConfiguration.java @@ -0,0 +1,122 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jms.hornetq; + +import java.util.Collection; +import java.util.List; + +import org.hornetq.jms.server.config.JMSConfiguration; +import org.hornetq.jms.server.config.JMSQueueConfiguration; +import org.hornetq.jms.server.config.TopicConfiguration; +import org.hornetq.jms.server.config.impl.JMSConfigurationImpl; +import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl; +import org.hornetq.jms.server.config.impl.TopicConfigurationImpl; +import org.hornetq.jms.server.embedded.EmbeddedJMS; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; + +/** + * Configuration used to create the embedded HornetQ server. + * + * @author Phillip Webb + * @author Stephane Nicoll + * @since 1.2.0 + */ +@Configuration +@ConditionalOnClass(name = HornetQConnectionFactoryFactory.EMBEDDED_JMS_CLASS) +@ConditionalOnProperty(prefix = "spring.hornetq.embedded", name = "enabled", havingValue = "true", matchIfMissing = true) +class HornetQEmbeddedServerConfiguration { + + @Autowired + private HornetQProperties properties; + + @Autowired(required = false) + private List configurationCustomizers; + + @Autowired(required = false) + private List queuesConfiguration; + + @Autowired(required = false) + private List topicsConfiguration; + + @Bean + @ConditionalOnMissingBean + public org.hornetq.core.config.Configuration hornetQConfiguration() { + return new HornetQEmbeddedConfigurationFactory(this.properties) + .createConfiguration(); + } + + @Bean(initMethod = "start", destroyMethod = "stop") + @ConditionalOnMissingBean + public EmbeddedJMS hornetQServer(org.hornetq.core.config.Configuration configuration, + JMSConfiguration jmsConfiguration) { + EmbeddedJMS server = new EmbeddedJMS(); + customize(configuration); + server.setConfiguration(configuration); + server.setJmsConfiguration(jmsConfiguration); + server.setRegistry(new HornetQNoOpBindingRegistry()); + return server; + } + + private void customize(org.hornetq.core.config.Configuration configuration) { + if (this.configurationCustomizers != null) { + AnnotationAwareOrderComparator.sort(this.configurationCustomizers); + for (HornetQConfigurationCustomizer customizer : this.configurationCustomizers) { + customizer.customize(configuration); + } + } + } + + @Bean + @ConditionalOnMissingBean + public JMSConfiguration hornetQJmsConfiguration() { + JMSConfiguration configuration = new JMSConfigurationImpl(); + addAll(configuration.getQueueConfigurations(), this.queuesConfiguration); + addAll(configuration.getTopicConfigurations(), this.topicsConfiguration); + addQueues(configuration, this.properties.getEmbedded().getQueues()); + addTopics(configuration, this.properties.getEmbedded().getTopics()); + return configuration; + } + + private void addAll(List list, Collection items) { + if (items != null) { + list.addAll(items); + } + } + + private void addQueues(JMSConfiguration configuration, String[] queues) { + boolean persistent = this.properties.getEmbedded().isPersistent(); + for (String queue : queues) { + configuration.getQueueConfigurations().add( + new JMSQueueConfigurationImpl(queue, null, persistent, "/queue/" + + queue)); + } + } + + private void addTopics(JMSConfiguration configuration, String[] topics) { + for (String topic : topics) { + configuration.getTopicConfigurations().add( + new TopicConfigurationImpl(topic, "/topic/" + topic)); + } + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQXAConnectionFactoryConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQXAConnectionFactoryConfiguration.java new file mode 100644 index 0000000000..ae7d5b1b6a --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQXAConnectionFactoryConfiguration.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jms.hornetq; + +import javax.jms.ConnectionFactory; +import javax.transaction.TransactionManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hornetq.jms.client.HornetQXAConnectionFactory; +import org.hornetq.jms.server.embedded.EmbeddedJMS; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.jta.XAConnectionFactoryWrapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for HornetQ XA {@link ConnectionFactory}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +@Configuration +@ConditionalOnMissingBean(ConnectionFactory.class) +@ConditionalOnClass(TransactionManager.class) +@ConditionalOnBean(XAConnectionFactoryWrapper.class) +class HornetQXAConnectionFactoryConfiguration { + + private static Log logger = LogFactory + .getLog(HornetQEmbeddedServerConfiguration.class); + + // Ensure JMS is setup before XA + @Autowired(required = false) + private EmbeddedJMS embeddedJMS; + + @Bean + public ConnectionFactory jmsConnectionFactory(HornetQProperties properties, + XAConnectionFactoryWrapper wrapper) throws Exception { + if (this.embeddedJMS != null && logger.isDebugEnabled()) { + logger.debug("Using embdedded HornetQ broker with XA"); + } + return wrapper.wrapConnectionFactory(new HornetQConnectionFactoryFactory( + properties).createConnectionFactory(HornetQXAConnectionFactory.class)); + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java index c69d1d524f..c1bcba116a 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java @@ -24,7 +24,6 @@ import org.junit.Test; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQProperties; import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -49,6 +48,10 @@ import static org.junit.Assert.assertTrue; */ public class JmsAutoConfigurationTests { + private static final String ACTIVEMQ_EMBEDDED_URL = "vm://localhost?broker.persistent=false"; + + private static final String ACTIVEMQ_NETWORK_URL = "tcp://localhost:61616"; + private AnnotationConfigApplicationContext context; @Test @@ -61,7 +64,7 @@ public class JmsAutoConfigurationTests { .getBean(JmsMessagingTemplate.class); assertEquals(jmsTemplate.getConnectionFactory(), connectionFactory); assertEquals(jmsTemplate, messagingTemplate.getJmsTemplate()); - assertEquals(ActiveMQProperties.DEFAULT_EMBEDDED_BROKER_URL, + assertEquals(ACTIVEMQ_EMBEDDED_URL, ((ActiveMQConnectionFactory) jmsTemplate.getConnectionFactory()) .getBrokerURL()); assertTrue("listener container factory should be created by default", @@ -158,7 +161,7 @@ public class JmsAutoConfigurationTests { assertNotNull(jmsTemplate); assertNotNull(connectionFactory); assertEquals(jmsTemplate.getConnectionFactory(), connectionFactory); - assertEquals(ActiveMQProperties.DEFAULT_NETWORK_BROKER_URL, + assertEquals(ACTIVEMQ_NETWORK_URL, ((ActiveMQConnectionFactory) jmsTemplate.getConnectionFactory()) .getBrokerURL()); } @@ -188,8 +191,7 @@ public class JmsAutoConfigurationTests { assertEquals(jmsTemplate.getConnectionFactory(), pool); ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) pool .getConnectionFactory(); - assertEquals(ActiveMQProperties.DEFAULT_EMBEDDED_BROKER_URL, - factory.getBrokerURL()); + assertEquals(ACTIVEMQ_EMBEDDED_URL, factory.getBrokerURL()); } @Test @@ -204,8 +206,7 @@ public class JmsAutoConfigurationTests { assertEquals(jmsTemplate.getConnectionFactory(), pool); ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) pool .getConnectionFactory(); - assertEquals(ActiveMQProperties.DEFAULT_NETWORK_BROKER_URL, - factory.getBrokerURL()); + assertEquals(ACTIVEMQ_NETWORK_URL, factory.getBrokerURL()); } @Test @@ -257,6 +258,7 @@ public class JmsAutoConfigurationTests { @Configuration protected static class TestConfiguration2 { + @Bean ConnectionFactory connectionFactory() { return new ActiveMQConnectionFactory() { @@ -265,10 +267,12 @@ public class JmsAutoConfigurationTests { } }; } + } @Configuration protected static class TestConfiguration3 { + @Bean JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) { JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory); @@ -280,6 +284,7 @@ public class JmsAutoConfigurationTests { @Configuration protected static class TestConfiguration4 implements BeanPostProcessor { + @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { @@ -295,6 +300,7 @@ public class JmsAutoConfigurationTests { throws BeansException { return bean; } + } @Configuration diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java index 699bcdc5c1..68ae0ed1ae 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java @@ -17,67 +17,50 @@ package org.springframework.boot.autoconfigure.jms.activemq; import org.junit.Test; -import org.springframework.boot.test.EnvironmentTestUtils; -import org.springframework.core.env.StandardEnvironment; import static org.junit.Assert.assertEquals; /** - * Tests for {@link ActiveMQProperties}. + * Tests for {@link ActiveMQProperties} and ActiveMQConnectionFactoryFactory. * * @author Stephane Nicoll */ public class ActiveMQPropertiesTests { - private final ActiveMQProperties properties = new ActiveMQProperties(); - - private final StandardEnvironment environment = new StandardEnvironment(); + private static final String DEFAULT_EMBEDDED_BROKER_URL = "vm://localhost?broker.persistent=false"; - @Test - public void determineBrokerUrlDefault() { - assertEquals(ActiveMQProperties.DEFAULT_EMBEDDED_BROKER_URL, - ActiveMQProperties.determineBrokerUrl(this.environment)); - } + private static final String DEFAULT_NETWORK_BROKER_URL = "tcp://localhost:61616"; - @Test - public void determineBrokerUrlVmBrokerUrl() { - EnvironmentTestUtils.addEnvironment(this.environment, - "spring.activemq.brokerUrl:vm://localhost?persistent=true"); - assertEquals("vm://localhost?persistent=true", - ActiveMQProperties.determineBrokerUrl(this.environment)); - } - - @Test - public void determineBrokerUrlInMemoryFlag() { - EnvironmentTestUtils.addEnvironment(this.environment, - "spring.activemq.inMemory:false"); - assertEquals(ActiveMQProperties.DEFAULT_NETWORK_BROKER_URL, - ActiveMQProperties.determineBrokerUrl(this.environment)); - } + private final ActiveMQProperties properties = new ActiveMQProperties(); @Test public void getBrokerUrlIsInMemoryByDefault() { - assertEquals(ActiveMQProperties.DEFAULT_EMBEDDED_BROKER_URL, - this.properties.determineBrokerUrl()); + assertEquals(DEFAULT_EMBEDDED_BROKER_URL, new ActiveMQConnectionFactoryFactory( + this.properties).determineBrokerUrl()); } @Test public void getBrokerUrlUseExplicitBrokerUrl() { this.properties.setBrokerUrl("vm://foo-bar"); - assertEquals("vm://foo-bar", this.properties.determineBrokerUrl()); + assertEquals("vm://foo-bar", + new ActiveMQConnectionFactoryFactory(this.properties) + .determineBrokerUrl()); } @Test public void getBrokerUrlWithInMemorySetToFalse() { this.properties.setInMemory(false); - assertEquals(ActiveMQProperties.DEFAULT_NETWORK_BROKER_URL, - this.properties.determineBrokerUrl()); + assertEquals(DEFAULT_NETWORK_BROKER_URL, new ActiveMQConnectionFactoryFactory( + this.properties).determineBrokerUrl()); } @Test public void getExplicitBrokerUrlAlwaysWins() { this.properties.setBrokerUrl("vm://foo-bar"); this.properties.setInMemory(false); - assertEquals("vm://foo-bar", this.properties.determineBrokerUrl()); + assertEquals("vm://foo-bar", + new ActiveMQConnectionFactoryFactory(this.properties) + .determineBrokerUrl()); } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java index f304de8248..d96d2a3cd6 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java @@ -43,11 +43,13 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; import org.springframework.jms.core.SessionCallback; @@ -183,10 +185,8 @@ public class HornetQAutoConfigurationTests { @Test public void embeddedServiceWithCustomJmsConfiguration() { - load(CustomJmsConfiguration.class, "spring.hornetq.embedded.queues=Queue1,Queue2"); // Ignored - // with - // custom - // config + // Ignored with custom config + load(CustomJmsConfiguration.class, "spring.hornetq.embedded.queues=Queue1,Queue2"); DestinationChecker checker = new DestinationChecker(this.context); checker.checkQueue("custom", true); // See CustomJmsConfiguration @@ -317,7 +317,7 @@ public class HornetQAutoConfigurationTests { String... environment) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.register(config); - applicationContext.register(HornetQAutoConfiguration.class, + applicationContext.register(HornetQAutoConfigurationWithoutXA.class, JmsAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(applicationContext, environment); applicationContext.refresh(); @@ -417,4 +417,11 @@ public class HornetQAutoConfigurationTests { } } + @Configuration + @EnableConfigurationProperties(HornetQProperties.class) + @Import({ HornetQEmbeddedServerConfiguration.class, + HornetQConnectionFactoryConfiguration.class }) + protected static class HornetQAutoConfigurationWithoutXA { + } + }