You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Christian Schubert-Huff (Jira)" <ji...@apache.org> on 2023/01/22 13:49:00 UTC

[jira] [Updated] (CAMEL-18964) camel-activemq - JMS connection factory used if defined

     [ https://issues.apache.org/jira/browse/CAMEL-18964?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Christian Schubert-Huff updated CAMEL-18964:
--------------------------------------------
    Description: 
We implemented am IBM-MQ to ActiveMQ bridge in camel-main, using camel-activemq and camel-jms for IBM-MQ, very similar to the documented [EIP|https://camel.apache.org/components/3.18.x/eips/messaging-bridge.html].

This requires the definition of a custom connection factory, which is then set as connection factory of the JMS component:
{noformat}
camel.beans.mqConnectionFactory = #class:com.ibm.mq.jms.MQConnectionFactory
camel.beans.mqConnectionFactory.HOSTNAME= mqhost

camel.component.jms.connection-factory = #bean:mqConnectionFactory
{noformat}
Next, we configured the ActiveMQ component _without_ defining an explicit connection factory, like this:
{noformat}
camel.component.activemq.broker-url = activemqhost
camel.component.activemq.username = jay
camel.component.activemq.password = unit
{noformat}
We expected this to just work. Instead, the ActiveMQ component began using the mqConnectionFactory bean as its own connection factory, and the application started throwing errors.

This occurs regardless of the value of {{camel.component.activemq.allow-auto-wired-connection-factory}} (which defaults to true).

This can be reproduced with the following unit test (which uses ActiveMQConnectionFactory so it doesn't depend on proprietary JARs):
{code:java}
@Test
public void testBindJmsConnectionFactory() {
    Main main = new Main();
    main.configure().addRoutesBuilder(new MyRouteBuilder());

    // defining a connection factory for the JMS component
    main.addProperty("camel.beans.jmscf", "#class:org.apache.activemq.ActiveMQConnectionFactory");
    main.addProperty("camel.beans.jmscf.brokerURL", "jmshost");
    main.addProperty("camel.component.jms.connection-factory", "#bean:jmscf");

    main.addProperty("camel.component.activemq.broker-url", "activemqhost");
    main.addProperty("camel.component.activemq.username", "jay");
    main.addProperty("camel.component.activemq.password", "unit");
    main.addProperty("camel.component.activemq.allow-auto-wired-connection-factory", "false");

    main.start();

    CamelContext camelContext = main.getCamelContext();
    assertNotNull(camelContext);

    ActiveMQConnectionFactory connectionFactory = camelContext.getRegistry().lookupByNameAndType("jmscf", ActiveMQConnectionFactory.class);
    assertNotNull(connectionFactory);
    
    JmsComponent jmsComponent = camelContext.getComponent("jms", JmsComponent.class);
    assertNotNull(jmsComponent);
    assertSame(connectionFactory, jmsComponent.getConnectionFactory());

    ActiveMQComponent activeMqComponent = camelContext.getComponent("activemq", ActiveMQComponent.class);
    assertNotNull(activeMqComponent);
    assertEquals("activemqhost", activeMqComponent.getBrokerURL());
    assertEquals("jay", activeMqComponent.getUsername());
    assertEquals("unit", activeMqComponent.getPassword());
    assertNotSame(connectionFactory, activeMqComponent.getConnectionFactory());

    main.stop();
}
{code}
There is a workaround, which is to define an explicit connection factory on the ActiveMQ component:
{noformat}
camel.beans.amqcf = #class:org.apache.activemq.ActiveMQConnectionFactory
camel.beans.amqcf.brokerURL = activemqhost

camel.component.activemq.connection-factory = #bean:amqcf 
{noformat}

  was:
We implemented am IBM-MQ to ActiveMQ bridge in camel-main, using camel-activemq and camel-jms for IBM-MQ, very similar to the documented [EIP|https://camel.apache.org/components/3.18.x/eips/messaging-bridge.html].

This requires the definition of a custom connection factory, which is then set as connection factory of the JMS component:
{noformat}
camel.beans.mqConnectionFactory = #class:com.ibm.mq.jms.MQConnectionFactory
camel.beans.mqConnectionFactory.HOSTNAME= mqhost

camel.component.jms.connection-factory = #bean:mqConnectionFactory
{noformat}
Next, we configured the ActiveMQ component _without_ defining an explicit connection factory, like this:
{noformat}
camel.component.activemq.broker-url = activemqhost
camel.component.activemq.username = jay
camel.component.activemq.password = unit
{noformat}
We expected this to just work. Instead, the ActiveMQ component began using the mqConnectionFactory bean as its own connection factory, and the application started throwing errors.

This occurs regardless of the value of {{camel.component.activemq.allow-auto-wired-connection-factory}} (which defaults to true).

This can be reproduced with the following unit test (which uses ActiveMQConnectionFactory so it doesn't depend on proprietary JARs):
{code:java}
@Test
public void testBindJmsConnectionFactory() {
    Main main = new Main();
    main.configure().addRoutesBuilder(new MyRouteBuilder());

    // defining a connection factory for the JMS component
    main.addProperty("camel.beans.jmscf", "#class:org.apache.activemq.ActiveMQConnectionFactory");
    main.addProperty("camel.beans.jmscf.brokerURL", "jmshost");
    main.addProperty("camel.component.jms.connection-factory", "#bean:jmscf");

    main.addProperty("camel.component.activemq.broker-url", "activemqhost");
    main.addProperty("camel.component.activemq.username", "jay");
    main.addProperty("camel.component.activemq.password", "unit");
    main.addProperty("camel.component.activemq.allow-auto-wired-connection-factory", "false");

    main.start();

    CamelContext camelContext = main.getCamelContext();
    assertNotNull(camelContext);

    ActiveMQConnectionFactory connectionFactory = camelContext.getRegistry().lookupByNameAndType("jmscf", ActiveMQConnectionFactory.class);
    assertNotNull(connectionFactory);
    
    JmsComponent jmsComponent = camelContext.getComponent("jms", JmsComponent.class);
    assertNotNull(jmsComponent);
    assertSame(connectionFactory, jmsComponent.getConnectionFactory());

    ActiveMQComponent activeMqComponent = camelContext.getComponent("activemq", ActiveMQComponent.class);
    assertNotNull(activeMqComponent);
    assertEquals("activemqhost", activeMqComponent.getBrokerURL());
    assertEquals("jay", activeMqComponent.getUsername());
    assertEquals("unit", activeMqComponent.getPassword());
    assertNotSame(connectionFactory, activeMqComponent.getConnectionFactory());

    main.stop();
}
{code}
This is a workaround, which is to define an explicit connection factory on the ActiveMQ component:
{noformat}
camel.beans.amqcf = #class:org.apache.activemq.ActiveMQConnectionFactory
camel.beans.amqcf.brokerURL = activemqhost

camel.component.activemq.connection-factory = #bean:amqcf 
{noformat}


> camel-activemq - JMS connection factory used if defined
> -------------------------------------------------------
>
>                 Key: CAMEL-18964
>                 URL: https://issues.apache.org/jira/browse/CAMEL-18964
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-activemq, camel-jms, camel-main
>    Affects Versions: 3.18.1, 3.20.1
>         Environment: camel-main, camel-activemq, camel-jms, jdk11, linux
>            Reporter: Christian Schubert-Huff
>            Priority: Minor
>
> We implemented am IBM-MQ to ActiveMQ bridge in camel-main, using camel-activemq and camel-jms for IBM-MQ, very similar to the documented [EIP|https://camel.apache.org/components/3.18.x/eips/messaging-bridge.html].
> This requires the definition of a custom connection factory, which is then set as connection factory of the JMS component:
> {noformat}
> camel.beans.mqConnectionFactory = #class:com.ibm.mq.jms.MQConnectionFactory
> camel.beans.mqConnectionFactory.HOSTNAME= mqhost
> camel.component.jms.connection-factory = #bean:mqConnectionFactory
> {noformat}
> Next, we configured the ActiveMQ component _without_ defining an explicit connection factory, like this:
> {noformat}
> camel.component.activemq.broker-url = activemqhost
> camel.component.activemq.username = jay
> camel.component.activemq.password = unit
> {noformat}
> We expected this to just work. Instead, the ActiveMQ component began using the mqConnectionFactory bean as its own connection factory, and the application started throwing errors.
> This occurs regardless of the value of {{camel.component.activemq.allow-auto-wired-connection-factory}} (which defaults to true).
> This can be reproduced with the following unit test (which uses ActiveMQConnectionFactory so it doesn't depend on proprietary JARs):
> {code:java}
> @Test
> public void testBindJmsConnectionFactory() {
>     Main main = new Main();
>     main.configure().addRoutesBuilder(new MyRouteBuilder());
>     // defining a connection factory for the JMS component
>     main.addProperty("camel.beans.jmscf", "#class:org.apache.activemq.ActiveMQConnectionFactory");
>     main.addProperty("camel.beans.jmscf.brokerURL", "jmshost");
>     main.addProperty("camel.component.jms.connection-factory", "#bean:jmscf");
>     main.addProperty("camel.component.activemq.broker-url", "activemqhost");
>     main.addProperty("camel.component.activemq.username", "jay");
>     main.addProperty("camel.component.activemq.password", "unit");
>     main.addProperty("camel.component.activemq.allow-auto-wired-connection-factory", "false");
>     main.start();
>     CamelContext camelContext = main.getCamelContext();
>     assertNotNull(camelContext);
>     ActiveMQConnectionFactory connectionFactory = camelContext.getRegistry().lookupByNameAndType("jmscf", ActiveMQConnectionFactory.class);
>     assertNotNull(connectionFactory);
>     
>     JmsComponent jmsComponent = camelContext.getComponent("jms", JmsComponent.class);
>     assertNotNull(jmsComponent);
>     assertSame(connectionFactory, jmsComponent.getConnectionFactory());
>     ActiveMQComponent activeMqComponent = camelContext.getComponent("activemq", ActiveMQComponent.class);
>     assertNotNull(activeMqComponent);
>     assertEquals("activemqhost", activeMqComponent.getBrokerURL());
>     assertEquals("jay", activeMqComponent.getUsername());
>     assertEquals("unit", activeMqComponent.getPassword());
>     assertNotSame(connectionFactory, activeMqComponent.getConnectionFactory());
>     main.stop();
> }
> {code}
> There is a workaround, which is to define an explicit connection factory on the ActiveMQ component:
> {noformat}
> camel.beans.amqcf = #class:org.apache.activemq.ActiveMQConnectionFactory
> camel.beans.amqcf.brokerURL = activemqhost
> camel.component.activemq.connection-factory = #bean:amqcf 
> {noformat}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)