You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2023/01/06 11:42:00 UTC

[jira] [Updated] (CAMEL-18865) camel-main - Setters not invoked on bean that implements Map

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

Claus Ibsen updated CAMEL-18865:
--------------------------------
    Fix Version/s: 3.21.0

> camel-main - Setters not invoked on bean that implements Map
> ------------------------------------------------------------
>
>                 Key: CAMEL-18865
>                 URL: https://issues.apache.org/jira/browse/CAMEL-18865
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-main
>    Affects Versions: 3.20.0
>         Environment: jdk11, camel-main, camel-jms, IBM-MQ 9.2 (https://mvnrepository.com/artifact/com.ibm.mq/com.ibm.mq.allclient)
>            Reporter: Christian Schubert-Huff
>            Assignee: Claus Ibsen
>            Priority: Minor
>             Fix For: 3.21.0
>
>
> We are having trouble configuring camel-jms with IBM-MQ as runtime implementation, using camel-main.
> Doing so requires the declaration of a connection factory, which, in our case, is [com.ibm.mq.jms.MQConnectionFactory|https://www.ibm.com/docs/api/v1/content/SSFKSJ_9.2.0/com.ibm.mq.javadoc.doc/WMQJMSClasses/com/ibm/mq/jms/MQConnectionFactory.html]. Unfortunately, this class implements both {{javax.jms.ConnectionFactory}} and {{{}java.util.Map<java.lang.String,java.lang.Object>{}}}. Also, the setters of that class have side effects, that are non-trivial to reproduce.
> What was really troubling us was that, contrary to intuition, defining a bean like this:
> {code:java}
> camel.beans.mqConnectionFactory = #class:com.ibm.mq.jms.MQConnectionFactory
> camel.beans.mqConnectionFactory.hostName = mqhost
> {code}
> does not actually invoke the setHostName method on the factory. Instead, value "mqhost" is put under key "hostName" into the map.
> Reproduction can be achieved with a quick custom class, like this:
> {code:java}
> package org.apache.camel.main;
> import java.util.HashMap;
> public class MyFooFactory extends HashMap<String, Object> {
>     private String hostName;
>     public String getHostName() {
>         return hostName;
>     }
>     public void setHostName(String hostName) {
>         this.hostName = hostName;
>     }
> }
> {code}
> and a unit test, which checks for the hostName:
> {code:java}
>     @Test
>     public void testBindBeansDottedHybridMap() {
>         Main main = new Main();
>         main.configure().addRoutesBuilder(new MyRouteBuilder());
>         // defining a factory bean
>         main.addProperty("camel.beans.myfactory", "#class:org.apache.camel.main.MyFooFactory");
>         main.addProperty("camel.beans.myfactory.hostName", "localhost");
>         main.start();
>         CamelContext camelContext = main.getCamelContext();
>         assertNotNull(camelContext);
>         Object bean = camelContext.getRegistry().lookupByName("myfactory");
>         assertNotNull(bean);
>         assertInstanceOf(MyFooFactory.class, bean);
>         MyFooFactory factory = (MyFooFactory) bean;
>         assertEquals("localhost", factory.getHostName());
>         main.stop();
>     }
> {code}
> For a custom bean that is under our own control, I would consider implementing java.util.Map and having additional custom getters and setters with side-effects to be invalid, but the IBM-MQ JMS client is out of our control - and required for our use case.
> If the dotted annotation is used, it may be preferable to check for a suitable setter first, and only if that is missing, to check if the bean implements java.util.Map.



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