Spring Boot(バージョン1.4.X)で組み込みActiveMQをセットアップして実行する簡単な例に従いました。例へのリンクはこちら https://spring.io/guides/gs/messaging-jms/
私のクラスは次のように構成されています:
@SpringBootApplication
@EnableJms
public class Application {
@Autowired
ConfigurableApplicationContext context;
@Bean
JmsListenerContainerFactory<?> myJmsContainerFactory(ConnectionFactory connectionFactory) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
return factory;
}
@JmsListener(destination = "mailbox-destination", containerFactory = "myJmsContainerFactory")
public void receiveMessage(String message) {
System.out.println("Message received: " + message);
context.close();
}
public static void main(String[] args) throws Exception {
FileSystemUtils.deleteRecursively(new File("active-data"));
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
JmsTemplate template = context.getBean(JmsTemplate.class);
MessageCreator messageCreator = new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("Test");
}
};
template.send("mailbox-destination", messageCreator);
}
}
そして、以下のようなbuild.gradle:
apply plugin: 'Java'
apply plugin: 'maven'
group = 'jms.activemq'
version = '0.0.1-SNAPSHOT'
description = """jms.activemq"""
sourceCompatibility = 1.5
targetCompatibility = 1.5
repositories {
maven { url "http://repo.maven.Apache.org/maven2" }
}
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-activemq', version:'1.4.0.RELEASE'
testCompile(group: 'org.springframework.boot', name: 'spring-boot-starter-test', version:'1.4.0.RELEASE') {
exclude(module: 'commons-logging')
}
}
これまでのところすべてがうまく機能しますが(application.propertiesを空のままにしておく限り)、application.propertiesファイルに次を追加してブローカーURLを設定しようとすると(リモートクライアントが接続できるように):
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
例外が発生します:
2016-08-03 12:46:00.938 WARN 88180 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.jms.config.internalJmsListenerEndpointRegistry'; nested exception is org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: Java.net.ConnectException: Connection refused: connect
2016-08-03 12:46:00.939 INFO 88180 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
2016-08-03 12:46:00.945 INFO 88180 --- [ main] utoConfigurationReportLoggingInitializer :
org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.jms.config.internalJmsListenerEndpointRegistry'; nested exception is org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: Java.net.ConnectException: Connection refused: connect
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.Java:176) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.Java:51) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.Java:346) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.Java:149) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.Java:112) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.Java:874) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:544) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:759) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.Java:369) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:313) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at jms.activemq.Application.main(Application.Java:37) [main/:na]
Caused by: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: Java.net.ConnectException: Connection refused: connect
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.Java:316) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.Java:169) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.listener.AbstractJmsListeningContainer.start(AbstractJmsListeningContainer.Java:273) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.config.JmsListenerEndpointRegistry.startIfNecessary(JmsListenerEndpointRegistry.Java:243) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.config.JmsListenerEndpointRegistry.start(JmsListenerEndpointRegistry.Java:206) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.Java:173) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
... 12 common frames omitted
Caused by: javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: Java.net.ConnectException: Connection refused: connect
at org.Apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.Java:36) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.Java:373) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.Java:303) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.Java:243) ~[activemq-client-5.13.4.jar:5.13.4]
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.Java:180) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.listener.AbstractJmsListeningContainer.createSharedConnection(AbstractJmsListeningContainer.Java:413) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.listener.AbstractJmsListeningContainer.establishSharedConnection(AbstractJmsListeningContainer.Java:381) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.listener.AbstractJmsListeningContainer.doStart(AbstractJmsListeningContainer.Java:285) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.listener.SimpleMessageListenerContainer.doStart(SimpleMessageListenerContainer.Java:210) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jms.listener.AbstractJmsListeningContainer.start(AbstractJmsListeningContainer.Java:270) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE]
... 15 common frames omitted
Caused by: Java.net.ConnectException: Connection refused: connect
at Java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.8.0_92]
at Java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.Java:85) ~[na:1.8.0_92]
at Java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.Java:350) ~[na:1.8.0_92]
at Java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.Java:206) ~[na:1.8.0_92]
at Java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.Java:188) ~[na:1.8.0_92]
at Java.net.PlainSocketImpl.connect(PlainSocketImpl.Java:172) ~[na:1.8.0_92]
at Java.net.SocksSocketImpl.connect(SocksSocketImpl.Java:392) ~[na:1.8.0_92]
at Java.net.Socket.connect(Socket.Java:589) ~[na:1.8.0_92]
at org.Apache.activemq.transport.tcp.TcpTransport.connect(TcpTransport.Java:525) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.transport.tcp.TcpTransport.doStart(TcpTransport.Java:488) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.util.ServiceSupport.start(ServiceSupport.Java:55) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.transport.AbstractInactivityMonitor.start(AbstractInactivityMonitor.Java:168) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.transport.InactivityMonitor.start(InactivityMonitor.Java:52) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.transport.TransportFilter.start(TransportFilter.Java:58) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.transport.WireFormatNegotiator.start(WireFormatNegotiator.Java:72) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.transport.TransportFilter.start(TransportFilter.Java:58) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.transport.TransportFilter.start(TransportFilter.Java:58) ~[activemq-client-5.13.4.jar:5.13.4]
at org.Apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.Java:353) ~[activemq-client-5.13.4.jar:5.13.4]
... 23 common frames omitted
いくつかのリンクを調べましたが、それでも問題の原因を特定できません。いくつかの洞察、または役立つ資料を本当に感謝します。
私の最初の考えは、Spring Bootはこれらの値を読み取ってActiveMQブローカーを構成するために使用するが、代わりにこれらの値を使用してブローカーに接続するように見えることです(ブローカーはすでに異なる設定で構成されています)。外部クライアント(ブローカーと同じJVMで実行されていない)がtcp:// localhost:61616を使用してブローカーにアクセスできるように、ブローカー構成を変更するにはどうすればよいですか
UPDATE:
here にリストされたブローカーを埋め込む方法の1つに従って、必要なURLをブローカーに埋め込み、接続することができます。しかし、Spring Bootはまだ先に進んでおり、以前と同じように1つ作成しているように見えるので、2つのブローカーを持つことになります。
基本的に、SpringApplication.run(Application.class、args)を呼び出す前に、このメソッドをmainメソッドの最初に追加するだけです。
BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61617");
broker.setPersistent(false);
broker.start();
2つのブローカーインスタンス(実行していると思われます)が存在するため、まったく正しくありません。
1)これはブローカーを埋め込む適切な方法ですか?
2)その場合、Spring Bootが別のSpring Bootを起動しないようにするにはどうすればよいですか? (spring-boot-starter-activemq依存関係を削除する必要はありません)。
前もって感謝します。
私はこれをしばらくの間遊んだ後、これを理解したと信じています。以下のようにDEFAULT組み込みブローカーへの接続を作成しようとしていたため、2つのインスタンスが実行されていると考えました(作成された/存在するかどうかを判断するため)。
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
しかし、どうやらSpring Bootは、その時点では存在せず作成しているようだ。
したがって、作成したインスタンスのみを実行するには、インスタンスの作成時にコネクタに追加したURL(この場合はtcp://localhost:61616
) の中に application.properties
以下のファイル
spring.activemq.broker-url=tcp://localhost:61616
spring Bootはこのインスタンスに接続し、別のインスタンスを作成しません。プロパティファイルに上記のエントリがない場合(または上記のようにvm:// localhostを使用して埋め込みインスタンスに接続しようとすると?...)、Spring Bootは先に進み、インスタンスをインスタンス化します。
私もこれを documentation で読みました:
Spring Bootは、ActiveMQがクラスパスで利用可能であることを検出したときにConnectionFactoryを構成することもできます。ブローカーが存在する場合、組み込みブローカーが開始され、自動的に構成されます(構成によってブローカーURLが指定されていない限り)。
しかし、私の意見では、それはうまく綴られていません(しかし、正しい方向に考えさせられました)。
異なる発見があった場合や、私の結論が正しくない場合はお知らせください。ありがとう!!!