0
votes

I'm trying to configure 3 Camel Routes to use the same JMS Component.

The problem is when I "have" to use the same component in these differents routes. When I do that, sometimes an error is showed up informing wasn't possible to connect to ActiveMQ is showed up. Is this happening because concurrency? If yes, I would like to know if is there possible configure this component at once and use it without this concurrency.

When I define the componenets with different name, it works. E.g: amq1, amq2 and amq3.

I'm using:

  • Apache Camel: 2.21
  • ActiveMQ Artemis: 1.5.6
  • Springboot: v1.5.16.RELEASE

The code: Method to create the JMS Component:

  public JmsComponent createComponent() {
    private ActiveMQJMSConnectionFactory connection;
    connection = new ActiveMQJMSConnectionFactory(host, user, password);
    connection.setMinLargeMessageSize(10000000);

    return JmsComponent.jmsComponent(connection);
  }

Adding the Component to route:

Route 1:

@Component
public class Route1 extends RouteBuilder {

  @Override
  public void configure() throws Exception {

    if (!getContext().getComponentNames().contains("amq")) {
      getContext().addComponent("amq", createComponent());
    }
    from("amq:" + queue)
      .routeId("Route1")
      .to("mock:result");
  }
}

Route 2:

@Component
public class Route2 extends RouteBuilder {

  @Override
  public void configure() throws Exception {

    if (!getContext().getComponentNames().contains("amq")) {
      getContext().addComponent("amq", createComponent());
    }
    from("amq:" + queue)
      .routeId("Route2")
      .to("mock:result");
  }
}

Route 3:

@Component
public class Route3 extends RouteBuilder {

  @Override
  public void configure() throws Exception {

    if (!getContext().getComponentNames().contains("amq")) {
      getContext().addComponent("amq", createComponent());
    }

    from("timer:Test?period=2s")
      .routeId("Route3")
      .setBody(simple("test"))
      .to("amq:" + queue);
  }
}

AMQ Broker acceptor:

      <acceptors>

         <acceptor name="artemis">tcp://0.0.0.0:61616?connectionTtl=60000;needClientAuth=true;supportAdvisory=false;anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor>

         <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor>

         <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>

         <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>

         <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>

      </acceptors>

The error:

Error processing exchange. Exchange[ID-op20190003-01-valenet-18-wlgfm-1560467581146-0-2]. Caused by: [org.springframework.jms.UncategorizedJmsException - Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Failed to create session factory; nested exception is ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ119007: Cannot connect to server(s). Tried with all available servers.]]
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Failed to create session factory; nested exception is ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ119007: Cannot connect to server(s). Tried with all available servers.]
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
    at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.send(JmsConfiguration.java:526)
    at org.apache.camel.component.jms.JmsProducer.doSend(JmsProducer.java:440)
    at org.apache.camel.component.jms.JmsProducer.processInOnly(JmsProducer.java:394)
    at org.apache.camel.component.jms.JmsProducer.process(JmsProducer.java:157)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.component.direct.DirectBlockingProducer.process(DirectBlockingProducer.java:53)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.component.direct.DirectBlockingProducer.process(DirectBlockingProducer.java:53)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
    at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:197)
    at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:79)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
Caused by: javax.jms.JMSException: Failed to create session factory
    at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:757)
    at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:265)
    at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:260)
    at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:180)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:474)
    ... 26 common frames omitted
Caused by: org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException: AMQ119007: Cannot connect to server(s). Tried with all available servers.
    at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:784)
    at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:755)
... 30 common frames omitted
1
Sure. Added in the question.Vitor
I wouldn't expect this issue to be related to concurrency since the acceptor is designed to service remote clients concurrently. What URI are you passing to the ActiveMQJMSConnectionFactory constructor? Do you see any exceptions in the broker's log? Have you tried this on the latest release of Artemis (i.e. 2.9.0)?Justin Bertram
I pass the follow URL, "tcp://<ip address>:61616". No I didn't see any execeptions in the logs. I tried only with the Artemis 2.6.3 because we are using Red Hat AMQ 7.2 that behinds is a Artemis 2.6.3. I'm trying to change Artemis Client from 1.5.6 (Current version in Fuse) to the same Broker version to verify if keeps with the same behavior.Vitor
So, this works fine if you use it in a single route, but not if you use it in two routes?Darius X.
Sorry for late response. Yes, and if I create a component for each route, works as well.Vitor

1 Answers

1
votes

You could create your own CamelContext by extending DefaultCamelContext and create the component there only once.

@Component
class YourCamelContext extends DefaultCamelContext {
  @PostConstruct
  private void addStuff() {
    addComponent("amq", createComponent());
...