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)