Sending message to Weblogic JMS Queue from a Camel

2019-07-08 06:46发布

问题:

I am trying to put a message on a Queue in Weblogic JMS, via a Camel Route.

My aim is to eventually configure a Route to consume the messages from the jms queue to which I publish the data from the earlier Route.

Here is my config:

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
            <prop key="java.naming.provider.url">t3://localhost:7001</prop>
            <!-- opional ... -->
            <prop key="java.naming.security.principal">weblogic</prop>
            <prop key="java.naming.security.credentials">weblogic</prop>
        </props>
    </property>
</bean>

<!-- Gets a Weblogic JMS Connection factory object from JDNI Server by jndiName--> 
<bean id="webLogicJmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="jndiName" value="jms/TestConnectionFactory" />  <!-- the connection factory object is store under this name -->
</bean>

<!-- Create a new WebLogic Jms Camel Component -->
<bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
   <property name="connectionFactory" ref="webLogicJmsConnectionFactory"/>
</bean>

My Route looks like this:

from("cxfrs:bean:rsServer")
     .setBody().body(TestRequest.class)
     .process(new Processor(){
        @Override
        public void process(Exchange exchange) throws Exception {
            TestRequest request = exchange.getIn().getBody(TestRequest.class);
            TestResponse response = new TestResponse();
            response.setAddress(request.getAddress());
            response.setName(request.getName());
        }

     }).to("wmq:queue:TestJMSQueue");

I am getting this exception when I try to execute this Route:

May 27, 2013 6:37:47 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse
WARNING: javax.ws.rs.WebApplicationException: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is weblogic.jms.common.JMSException: [JMSExceptions:045101]The destination name passed to createTopic or createQueue "TestJMSModule!TestJMSQueue" is invalid. If the destination name does not contain a "/" character then it must be the name of a distributed destination that is available in the cluster to which the client is attached. If it does contain a "/" character then the string before the "/" must be the name of a JMSServer or a ".". The string after the "/" is the name of a the desired destination. If the "./" version of the string is used then any destination with the given name on the local WLS server will be returned.
at org.apache.camel.component.cxf.jaxrs.CxfRsInvoker.returnResponse(CxfRsInvoker.java:149)
at org.apache.camel.component.cxf.jaxrs.CxfRsInvoker.asyncInvoke(CxfRsInvoker.java:104)
at org.apache.camel.component.cxf.jaxrs.CxfRsInvoker.performInvocation(CxfRsInvoker.java:57)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:167)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:94)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor
...
Caused by: weblogic.jms.common.JMSException: [JMSExceptions:045101]The destination name passed to createTopic or createQueue "TestJMSModule!TestJMSQueue" is invalid. If the destination name does not contain a "/" character then it must be the name of a distributed destination that is available in the cluster to which the client is attached. If it does contain a "/" character then the string before the "/" must be the name of a JMSServer or a ".". The string after the "/" is the name of a the desired destination. If the "./" version of the string is used then any destination with the given name on the local WLS server will be returned.
at weblogic.jms.frontend.FEManager.destinationCreate(FEManager.java:202)
at weblogic.jms.frontend.FEManager.invoke(FEManager.java:544)
at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:961)
at weblogic.messaging.dispatcher.DispatcherImpl.syncRequest(DispatcherImpl.java:184)
at weblogic.messaging.dispatcher.DispatcherImpl.dispatchSyncNoTran(DispatcherImpl.java:287)
at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSyncNoTran(DispatcherAdapter.java:59)
at weblogic.jms.client.JMSSession.createDestination(JMSSession.java:3118)
at weblogic.jms.client.JMSSession.createQueue(JMSSession.java:2514)

I followed the procedure to create a Queue mentioned here: https://blogs.oracle.com/soaproactive/entry/how_to_create_a_simple

I am creating a JMS Module(TestJMSModule) and in that I am creating a Queue(TestJMSQueue) and a connection factory inside it.

I am new to JMS and I know I am doing something wrong with the configurations either on the Camel side or the Weblogic side, but not able to figure out what. Any help would be greatly appreciated.

Thanks in advance.

回答1:

You need to create a JMS Server. Then you need to create a subdeployment in your JMS Module and then target the subdeployment to the JMS Server.

Then the syntax needs to be JMSServer/JMSModule!Queue



回答2:

Unfortunately I'm not an expert in WebLogic configuration. Client side config looks correct. The exception says the object name is not right. In the example you mentioned jndi name of the queue is "jms/TestJMSQueue", not just "TestJMSQueue". To me it means you should be using .to("wmq:queue:jms/TestJMSQueue"); instead.



回答3:

I was to integrate Spring (4.1.6) + Apache Camel (2.15.2) and consuming messages from a JMS Queue hosted on Oracle Weblogic (11g).

applicationContext.xml

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
            <prop key="java.naming.provider.url">t3://localhost:7001</prop>
            <prop key="java.naming.security.principal">weblogic</prop>
            <prop key="java.naming.security.credentials">welcome1</prop>
        </props>
    </property>
</bean>

<bean id="webLogicJmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <!-- Connection factory JNDI name -->
    <property name="jndiName" value="jms/TestConnectionFactory" />
</bean>

<bean id="weblogicJmsComponent" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="webLogicJmsConnectionFactory" />
</bean>

<camel:camelContext id="camel" xmlns:camel="http://camel.apache.org/schema/spring">
    <!-- Route to copy files -->
    <camel:route startupOrder="1">
        <camel:from uri="file:data/inbox?noop=true" />
        <camel:process ref="loggingProcessor" />
        <camel:to uri="file:data/outbox" />
    </camel:route>

    <!-- Route to read from JMS and process them in jmsReaderProcessor -->
    <camel:route startupOrder="2">
        <camel:from uri="weblogicJmsComponent:queue:TestJMSServer/TestJMSModule!TestJMSQueue" />
        <camel:process ref="jmsReaderProcessor" />
    </camel:route>
</camel:camelContext>

loggingProcessor and jmsReaderProcessor are two Camel Processor that just log the messages in/out from Exchange object.

public void process(Exchange exchange) throws Exception {
    LOG.info("begin process()");
    LOG.info("process() -- Got exchange: {}", exchange);

    Message messageIn = exchange.getIn();
    LOG.info("process() -- Got messageIn: {}", messageIn);

    LOG.info("process() -- Got messageIn.getBody(): {}", messageIn.getBody());

    Message messageOut = exchange.getOut();
    LOG.info("process() -- Got messageOut: {}", messageOut);

    LOG.info("end process()");
}

Kind Regards,

Cristian Manoliu