Search code examples
springapache-camelwildfly-8

Camel lookup RemoteConnectionFactory on Wildfly


I'm very new to Apache Camel and completely new to Spring. I'm tryin to send some JMS messages to the embedded hornetq in Wildfly (ver.8.1.0). Here is my code:

public class CamelJMS {

public static void main(String[] args) throws Exception {
    try {
        CamelContext cc = new DefaultCamelContext();

         Properties prop = new Properties();
         prop.put(Context.INITIAL_CONTEXT_FACTORY,
         "org.jboss.naming.remote.client.InitialContextFactory");
         prop.put(Context.URL_PKG_PREFIXES,
         "org.jboss.jms.jndi.JNDIProviderAdapter");
         prop.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
         prop.put(Context.SECURITY_PRINCIPAL,
         System.getProperty("username", "usr"));
         prop.put(Context.SECURITY_CREDENTIALS,
         System.getProperty("password", "pwd"));

         JndiTemplate jndiT = new JndiTemplate(prop);
         jndiT.bind("ccf", "jms/RemoteConnectionFactory");
         JndiObjectFactoryBean jndiCFB = new JndiObjectFactoryBean();
         jndiCFB.setJndiTemplate(jndiT);
         JmsComponent jmsC = JmsComponent.jmsComponent((ConnectionFactory)jndiCFB.getObject());

         cc.addComponent("jmsrc", jmsC);
         cc.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                System.out.println("Go!");
                onException(Throwable.class)
                .handled(true)
                .process(new Processor() {
                    @Override
                    public void process(Exchange arg0) throws Exception {
                        System.out.println("error.");
                        ((Exception) arg0.getProperty("CamelExceptionCaught", Exception.class)).printStackTrace();
                    }
                });
                from("file:///Users/Foo/Desktop/IN")
                .process(new Processor() {
                    @Override
                    public void process(Exchange arg0) throws Exception {
                        System.out.println(arg0.getIn().getHeader("CamelFileAbsolutePath", String.class));
                        System.out.println(arg0.getIn().getBody(String.class));
                    }
                })
                .to("jms:jms/generatoreQueue?connectionFactory=ccf");
            }
        });

        cc.start();
        Thread.sleep(10000);
        cc.stop();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

I'm sure about my Wildfly's configuration because I can access the same queue using a non Camel client. When I launch my client I got this error:

org.jboss.naming.remote.protocol.NamingIOException: Failed to bind [Root exception is java.io.IOException: Internal server error.]
at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:49)
at org.jboss.naming.remote.protocol.v1.Protocol$2.execute(Protocol.java:220)
at org.jboss.naming.remote.protocol.v1.Protocol$2.execute(Protocol.java:179)
at org.jboss.naming.remote.protocol.v1.RemoteNamingStoreV1.bind(RemoteNamingStoreV1.java:108)
at org.jboss.naming.remote.client.HaRemoteNamingStore$2.operation(HaRemoteNamingStore.java:288)
at org.jboss.naming.remote.client.HaRemoteNamingStore$2.operation(HaRemoteNamingStore.java:285)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:137)
at org.jboss.naming.remote.client.HaRemoteNamingStore.bind(HaRemoteNamingStore.java:284)
at org.jboss.naming.remote.client.RemoteContext.bind(RemoteContext.java:133)
at org.jboss.naming.remote.client.RemoteContext.bind(RemoteContext.java:137)
at javax.naming.InitialContext.bind(InitialContext.java:419)
at org.springframework.jndi.JndiTemplate$2.doInContext(JndiTemplate.java:198)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.bind(JndiTemplate.java:196)
at edu.pezzati.camel.jms.broker.CamelJMSBroker.main(CamelJMSBroker.java:38)
Caused by: java.io.IOException: Internal server error.
at org.jboss.naming.remote.protocol.v1.RemoteNamingServerV1$MessageReciever$1.run(RemoteNamingServerV1.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

Looking to the server log, I found this:

...
09:12:02,585 INFO  [org.jboss.as.naming] (default task-5) JBAS011806: Channel end notification received, closing channel Channel ID 793d9f9e (inbound) of Remoting c
onnection 4406e6f5 to /127.0.0.1:49289
09:12:20,121 ERROR [org.jboss.as.naming] (pool-1-thread-1) JBAS011807: Unexpected       internal error: java.lang.UnsupportedOperationException: JBAS011859: Naming context is read-only
    at org.jboss.as.naming.WritableServiceBasedNamingStore.requireOwner(WritableServiceBasedNamingStore.java:161)
    at org.jboss.as.naming.WritableServiceBasedNamingStore.bind(WritableServiceBasedNamingStore.java:66)
    at org.jboss.as.naming.NamingContext.bind(NamingContext.java:253)
    at org.jboss.naming.remote.protocol.v1.Protocol$2.handleServerMessage(Protocol.java:249)
    at org.jboss.naming.remote.protocol.v1.RemoteNamingServerV1$MessageReciever$1.run(RemoteNamingServerV1.java:73)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_45]
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45]
...

Of course I'm misconfiguring something in Spring's JndiTemplate but I can't figure out what.


Solution

  • I'm not familiar with Wildfly and only a little familiar with JBoss, but you said the configuration parameters should be correct. So based off of my experience configuring the Camel JmsComponent...

    Try this:

         Properties prop = new Properties();
         prop.put(Context.INITIAL_CONTEXT_FACTORY,
         "org.jboss.naming.remote.client.InitialContextFactory");
         prop.put(Context.URL_PKG_PREFIXES,
         "org.jboss.jms.jndi.JNDIProviderAdapter");
         prop.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
         prop.put(Context.SECURITY_PRINCIPAL,
         System.getProperty("username", "usr"));
         prop.put(Context.SECURITY_CREDENTIALS,
         System.getProperty("password", "pwd"));
    
         Context context = new InitialContext(prop);
         ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
    
         JmsComponent jmsC = new JmsComponent(connectionFactory);
    
         cc.addComponent("jms", jmsC);
    

    And change your endpoint to:

         .to("jms:queue:generatoreQueue");
    

    You shouldn't need the "jms/" in front of the queue name, and the component name should be the same as what you bound it to above in the addComponent method.