You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by jcraw62 <jc...@gmail.com> on 2015/09/18 06:48:44 UTC

Need help getting Camel ActiveMQComponent working in Tomcat web app

Need help getting Camel ActiveMQComponent working in Tomcat web app

I’m sure I’ve gone about this wrong but I’ve had no success after spending
several days.

I have a web app running on Tomcat 8.0.26. My requirement is to be able to
use pooled ActiveMQ 5.12.0 connections to have POJOs send messages to queues
whose names are built from the value of several POJO attributes at runtime.
These are fire and forget type messages. Simple enough right.

It seems that Camel ActiveMQComponent or Spring JMSTemplate was the
recommended approach. I chose to go with Camel (2.15.3) but have no
experience with Spring (4.2.1) or Camel and at least for now will only be
using Camel to provide POJOs access to pooled connections.

I have this Spring config coded in applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
         http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">

    <context:annotation-config/>

    <context:component-scan base-package="com.wtg.camel2"/>

    <camel:camelContext id="camel-client">
    </camel:camelContext>

    <bean id="foo" class="com.wtg.camel.MyBean"/>
    <bean id="jmsConnectionFactory"
          class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL"
value="failover:(tcp://dev2.wtgroupllc.com:xxxx,tcp://dev3.wtgroupllc.com:xxxx)?timeout=1000"
/>
    </bean>

    <bean id="pooledConnectionFactory"
          class="org.apache.activemq.pool.PooledConnectionFactory"
init-method="start" destroy-method="stop">
        <property name="maxConnections" value="3" />
        <property name="connectionFactory" ref="jmsConnectionFactory" />
    </bean>

    <bean id="jmsConfig"
          class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="pooledConnectionFactory"/>
    </bean>

    <bean id="activemq"
          class="org.apache.activemq.camel.component.ActiveMQComponent">
        <property name="configuration" ref="jmsConfig"/>
    </bean>
</beans>

… and referenced in my web.xml 

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/applicationContext.xml</param-value>

</context-param>



<listener>

   
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>


My POJO is:


public class CamelSender implements CamelContextAware {

    CamelContext camelContext;

    @EndpointInject(uri="activemq:foo.bar")
    ProducerTemplate producer;

    @BeanInject("activemq")
    ActiveMQComponent activeMQComponent;

    @BeanInject("foo")
    MyBean myBean;

    public void setCamelContext(CamelContext camelContext)  {
        this.camelContext=camelContext;
    }

    public CamelContext getCamelContext()  {
        return camelContext;
    } 

    @InOnly
    public void sendToQueue(String name, String msg) {
        camelContext = producer.getCamelContext();

        ProducerTemplate producerTemplate =
camelContext.createProducerTemplate();
        for (int i = 0; i < 3; i++) {
            producerTemplate.sendBody("activemq:queue:" + name, msg);    
        }
    }
}

Initially I thought I could just implement CamelContextAware and Camel would
take care of setting camelContext on the POJO when it was instantiated. It
was not instantiated as expected. Then I ran across
https://issues.apache.org/jira/browse/SMX4-1281 which seemed to indicate
that this would not work at least for OSGI implementations. 

At that point I tried to use @EndpointInject(uri="activemq:foo.bar") to
inject a ProducerTemplate thinking I could get the camelContext from the
template and handle the message send as coded in sendToQueue(String name,
String msg). Again I expected that Camel would inject an instance of
ProducerTemplate when CamelSender was instantiated (even though the endpoint
uri is a dummy endpoint – not defined anywhere).  I was wring again.

Lastly, from examples it looked like I could simply get Camel to inject the
activeMQ component I configured using @BeanInject("activemq"). Again I was
wrong and to prove it a 2nd time I configured and attempted to    
@BeanInject("foo").


What is the best way to solve my requirements? There is plenty I don’t
understand but what have I done wrong? 

Aside from configuring these beans correctly is there anything I would need
to do to handle startup and shutdown (clean up MQ connections, sessions,
etc.) or does Camel do this for me?

Finally, since I’m only interested in fire and forget messaging right now
should I be looking at @InOnly methods – is the only requirement that I must
include an @InOnly annotation before the method that will execeute fire and
forget as in the example above?

Thanks for helping to save what little sanity I have left.






--
View this message in context: http://camel.465427.n5.nabble.com/Need-help-getting-Camel-ActiveMQComponent-working-in-Tomcat-web-app-tp5771612.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Need help getting Camel ActiveMQComponent working in Tomcat web app

Posted by Claus Ibsen <cl...@gmail.com>.
Your pojo class CamelSender must be created by spring so it can
trigger the dependency injection.

You may need to add a @Component or whatever the spring annotation is
to mark a class for dependency injection.

On Fri, Sep 18, 2015 at 9:24 PM, jcraw62 <jc...@gmail.com> wrote:
> Claus,
>
> thank you for the prompt reply. So now I understand ProducerTemplate should
> be instantiated via Spring. I've configured:
>
>     <camel:camelContext id="camel-client">
>         <camel:template id="camelTemplate"
> defaultEndpoint="activemq:start"/>
>     </camel:camelContext>
>
> and still I do not get injection when I code:
>
> @Produce(uri = "activemq:start")
>     protected ProducerTemplate template;
>     public void sendToQueue(String name, String msg) {
>         for (int i = 0; i < 3; i++) {
>             template.sendBody("activemq:queue:" + name, msg);
>         }
>     }
>
> I see my configured beans in the app context but injection seems to fail
> regardless of which bean I try to inject using different injection
> annotations.
>
> I'm still conceptually missing something.
>
> Thanks.
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Need-help-getting-Camel-ActiveMQComponent-working-in-Tomcat-web-app-tp5771612p5771672.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2nd edition:
https://www.manning.com/books/camel-in-action-second-edition

Re: Need help getting Camel ActiveMQComponent working in Tomcat web app

Posted by jcraw62 <jc...@gmail.com>.
Claus,

thank you for the prompt reply. So now I understand ProducerTemplate should
be instantiated via Spring. I've configured:

    <camel:camelContext id="camel-client">
        <camel:template id="camelTemplate"
defaultEndpoint="activemq:start"/>
    </camel:camelContext>

and still I do not get injection when I code:

@Produce(uri = "activemq:start")
    protected ProducerTemplate template;
    public void sendToQueue(String name, String msg) {
        for (int i = 0; i < 3; i++) {
            template.sendBody("activemq:queue:" + name, msg);  
        }
    }

I see my configured beans in the app context but injection seems to fail
regardless of which bean I try to inject using different injection
annotations. 

I'm still conceptually missing something.

Thanks.



--
View this message in context: http://camel.465427.n5.nabble.com/Need-help-getting-Camel-ActiveMQComponent-working-in-Tomcat-web-app-tp5771612p5771672.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Need help getting Camel ActiveMQComponent working in Tomcat web app

Posted by Claus Ibsen <cl...@gmail.com>.
See this FAQ about producer template and also its javadoc
http://camel.apache.org/why-does-camel-use-too-many-threads-with-producertemplate.html

On Fri, Sep 18, 2015 at 6:48 AM, jcraw62 <jc...@gmail.com> wrote:
> Need help getting Camel ActiveMQComponent working in Tomcat web app
>
> I’m sure I’ve gone about this wrong but I’ve had no success after spending
> several days.
>
> I have a web app running on Tomcat 8.0.26. My requirement is to be able to
> use pooled ActiveMQ 5.12.0 connections to have POJOs send messages to queues
> whose names are built from the value of several POJO attributes at runtime.
> These are fire and forget type messages. Simple enough right.
>
> It seems that Camel ActiveMQComponent or Spring JMSTemplate was the
> recommended approach. I chose to go with Camel (2.15.3) but have no
> experience with Spring (4.2.1) or Camel and at least for now will only be
> using Camel to provide POJOs access to pooled connections.
>
> I have this Spring config coded in applicationContext.xml:
>
> <beans xmlns="http://www.springframework.org/schema/beans"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xmlns:camel="http://camel.apache.org/schema/spring"
>        xmlns:context="http://www.springframework.org/schema/context"
>        xsi:schemaLocation="
>          http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd
>          http://www.springframework.org/schema/context
> http://www.springframework.org/schema/context/spring-context.xsd
>          http://camel.apache.org/schema/spring
> http://camel.apache.org/schema/spring/camel-spring.xsd">
>
>     <context:annotation-config/>
>
>     <context:component-scan base-package="com.wtg.camel2"/>
>
>     <camel:camelContext id="camel-client">
>     </camel:camelContext>
>
>     <bean id="foo" class="com.wtg.camel.MyBean"/>
>     <bean id="jmsConnectionFactory"
>           class="org.apache.activemq.ActiveMQConnectionFactory">
>         <property name="brokerURL"
> value="failover:(tcp://dev2.wtgroupllc.com:xxxx,tcp://dev3.wtgroupllc.com:xxxx)?timeout=1000"
> />
>     </bean>
>
>     <bean id="pooledConnectionFactory"
>           class="org.apache.activemq.pool.PooledConnectionFactory"
> init-method="start" destroy-method="stop">
>         <property name="maxConnections" value="3" />
>         <property name="connectionFactory" ref="jmsConnectionFactory" />
>     </bean>
>
>     <bean id="jmsConfig"
>           class="org.apache.camel.component.jms.JmsConfiguration">
>         <property name="connectionFactory" ref="pooledConnectionFactory"/>
>     </bean>
>
>     <bean id="activemq"
>           class="org.apache.activemq.camel.component.ActiveMQComponent">
>         <property name="configuration" ref="jmsConfig"/>
>     </bean>
> </beans>
>
> … and referenced in my web.xml
>
> <context-param>
>
>     <param-name>contextConfigLocation</param-name>
>
>     <param-value>/WEB-INF/applicationContext.xml</param-value>
>
> </context-param>
>
>
>
> <listener>
>
>
> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
>
> </listener>
>
>
> My POJO is:
>
>
> public class CamelSender implements CamelContextAware {
>
>     CamelContext camelContext;
>
>     @EndpointInject(uri="activemq:foo.bar")
>     ProducerTemplate producer;
>
>     @BeanInject("activemq")
>     ActiveMQComponent activeMQComponent;
>
>     @BeanInject("foo")
>     MyBean myBean;
>
>     public void setCamelContext(CamelContext camelContext)  {
>         this.camelContext=camelContext;
>     }
>
>     public CamelContext getCamelContext()  {
>         return camelContext;
>     }
>
>     @InOnly
>     public void sendToQueue(String name, String msg) {
>         camelContext = producer.getCamelContext();
>
>         ProducerTemplate producerTemplate =
> camelContext.createProducerTemplate();
>         for (int i = 0; i < 3; i++) {
>             producerTemplate.sendBody("activemq:queue:" + name, msg);
>         }
>     }
> }
>
> Initially I thought I could just implement CamelContextAware and Camel would
> take care of setting camelContext on the POJO when it was instantiated. It
> was not instantiated as expected. Then I ran across
> https://issues.apache.org/jira/browse/SMX4-1281 which seemed to indicate
> that this would not work at least for OSGI implementations.
>
> At that point I tried to use @EndpointInject(uri="activemq:foo.bar") to
> inject a ProducerTemplate thinking I could get the camelContext from the
> template and handle the message send as coded in sendToQueue(String name,
> String msg). Again I expected that Camel would inject an instance of
> ProducerTemplate when CamelSender was instantiated (even though the endpoint
> uri is a dummy endpoint – not defined anywhere).  I was wring again.
>
> Lastly, from examples it looked like I could simply get Camel to inject the
> activeMQ component I configured using @BeanInject("activemq"). Again I was
> wrong and to prove it a 2nd time I configured and attempted to
> @BeanInject("foo").
>
>
> What is the best way to solve my requirements? There is plenty I don’t
> understand but what have I done wrong?
>
> Aside from configuring these beans correctly is there anything I would need
> to do to handle startup and shutdown (clean up MQ connections, sessions,
> etc.) or does Camel do this for me?
>
> Finally, since I’m only interested in fire and forget messaging right now
> should I be looking at @InOnly methods – is the only requirement that I must
> include an @InOnly annotation before the method that will execeute fire and
> forget as in the example above?
>
> Thanks for helping to save what little sanity I have left.
>
>
>
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Need-help-getting-Camel-ActiveMQComponent-working-in-Tomcat-web-app-tp5771612.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2nd edition:
https://www.manning.com/books/camel-in-action-second-edition