I have Jetty hightide 8.1.8.v20121106 running and have deployed a tiny webapp using jquery/javascript to listen onto a JMS topic and when a message is received it will display it on the page. I have a java app that will connect to a JMS topic and publish messages, I want those messages published by the Java app to be consumed by the webapp on Jetty.
Jetty is not connecting to tcp://localhost:61616 when the javascript webapp publishes a message or listens for a message. The logs show Jetty connecting to vm://localhost all the time. Is there any way to make Jetty use my ActiveMQ server instead of its own embedded one? Help is appreciated.
Config files below:
jetty-plus.xml
<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>jms/connectionFactory</Arg>
<Arg>
<New class="org.apache.activemq.ActiveMQConnectionFactory">
<Arg>tcp://localhost:61616</Arg>
</New>
</Arg>
</New>
<New id="interestingTopic" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>jms/interestingTopic</Arg>
<Arg>
<New class="org.apache.activemq.command.ActiveMQTopic">
<Arg>my.test</Arg>
</New>
</Arg>
</New>
web.xml for webapp
<web-app>
<context-param>
<param-name>org.apache.activemq.brokerURL</param-name>
<param-value>tcp://localhost:61616</param-value>
<description>The URL of the Message Broker to connect to</description>
</context-param>
<context-param>
<param-name>org.apache.activemq.embeddedBroker</param-name>
<param-value>true</param-value>
<description>Whether we should include an embedded broker or not</description>
</context-param>
<filter>
<filter-name>session</filter-name>
<filter-class>org.apache.activemq.web.SessionFilter</filter-class>
<!-- <filter-class>org.eclipse.jetty.continuation.ContinuationFilter</filter-class> -->
</filter>
<filter-mapping>
<filter-name>session</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.apache.activemq.web.SessionListener</listener-class>
</listener>
<servlet>
<servlet-name>AjaxServlet</servlet-name>
<servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MessageServlet</servlet-name>
<servlet-class>org.apache.activemq.web.MessageServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AjaxServlet</servlet-name>
<url-pattern>/amq/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MessageServlet</servlet-name>
<url-pattern>/message/*</url-pattern>
</servlet-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<resource-env-ref>
<resource-env-ref-name>jms/interestingTopic</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
</resource-env-ref>
<resource-ref>
<description>Connection Factory</description>
<res-ref-name>jms/connectionFactory</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
My Java script code for listening on the topic
window.onload = function() {
org.activemq.Amq.init({ uri: 'amq', logging: true, timeout: 45, clientId:('geo_1') });
};
var amq = org.activemq.Amq;
var msgTopic = 'topic://my.test';
var clientId = 'geo_1';
function addTopicListener() {
var myHandler = {
rcvMessage: function(message) {
//<message type="zmg">test test</message>
var type = message.getAttribute('type');
switch (type) {
case 'zmsg':
{
var text = message.childNodes[0].data;
document.getElementById('zmsg_container').innerHTML += ' | '+text;
break;
}
}
}
};
amq.addListener('myHandler', msgTopic, myHandler.rcvMessage);
};
function delTopicListener() {
amq.removeListener('myHandler', msgTopic);
}
And lastly the code in my Java app for publishing
private void init() throws NamingException {
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.setProperty(Context.PROVIDER_URL,"tcp://localhost:61616");
props.setProperty("topic.test", "my.test");
ctx = new InitialContext(props);
System.out.println("JMS Context Initialized");
}
private void connect() throws NamingException, JMSException {
connectionFactory = (TopicConnectionFactory)ctx.lookup("ConnectionFactory");
conn = connectionFactory.createTopicConnection();
myTopic = (Topic)ctx.lookup("test");
session = conn.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
publisher = session.createPublisher(myTopic);
System.out.println("JMS Connection started");
}
After literally scouring the internet and going through many websites about configuring Jetty and ActiveMQ; I finally came across a website that discusses clustering jetty with activemq and having jetty use the web-console of activemq (http://java.dzone.com/articles/activemq-configuring-multiple). That website really helped.
So I was just missing an extra XML configuration section in Jetty. With the XML config I have above, I had to append the following:
<New id="url" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>jmx/url</Arg>
<Arg>
<New class="java.lang.String">
<Arg>service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi,service:jmx:rmi:///jndi/rmi://localhost:1299/jmxrmi</Arg>
</New>
</Arg>
</New>
After that I started Jetty and ActiveMQ and sure enough jetty was connecting to ActiveMQ and not creating its own vm://localhost connection as it was doing before by default.
Thanks to those who helped, it allowed me to focus on my issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With