I am using an embedded ActiveMQ broker.
My goal is to find a way to detect when an external producer on a Queue lost it's connection.
I am starting the broker like this:
BrokerService broker = new BrokerService();
broker.addConnector("tcp://" + LISTEN_DEVICE_IP + ":" + port);
setLastMessagesPersistent(broker);
broker.start();
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
connection = factory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
And after that I tried to add a TransportListener:
((ActiveMQConnection) connection).addTransportListener(new TransportListener() {
public void transportResumed() {
System.out.println("resumed");
}
public void transportInterupted() {
System.out.println("interrupted");
}
public void onException(IOException arg0) {
System.out.println("ioexception: " + arg0);
}
public void onCommand(Object arg0) {
System.out.println("command: " + arg0);
}
});
I also register a consumer and ProducerListener like this:
Destination dest = session.createQueue(queuename);
MessageConsumer consumer = session.createConsumer(dest);
ProducerEventSource source = new ProducerEventSource(connection, dest);
System.out.println("Setting Producer Listener");
source.setProducerListener(prodevent -> {
System.out.println("producer status: " + prodevent.isStarted());
});
// Gets called from inside the broker's Thread and somehow causes deadlocks if I don't invoke this from the outside
new Thread(() -> {
try {
consumer.setMessageListener(new NetworkEventPlayerAdapter(objectMapper, event, gameEventManager, playerID));
} catch (Exception e) {
e.printStackTrace();
}
}).start();
Unfortunately neither the TransportListener, nor the ProducerListener give me any output when I forcefully quit another application that previously was added as a producer (Alt+F4). The broker surely notices though:
WARN | Transport Connection to: tcp://127.0.0.1:58988 failed: java.net.SocketException: Connection reset
WARN | Transport Connection to: tcp://127.0.0.1:58986 failed: java.net.SocketException: Connection reset
But I don't find a way to get a callback on those events in Java.
I also tried setting a custom IOExceptionHandler in the broker and adding an ExceptionListener to the connection. They also get never called.
You can use The Advisory Topics ActiveMQ.Advisory.Connection or even the ActiveMQ.Advisory.Producer.Queue ActiveMQ.Advisory.Producer.Topic , these provide the stats on connections of number of producers , check this link http://activemq.apache.org/advisory-message.html
a possible way is to parse the log-output for Connection reset
WARN | Transport Connection to: tcp://127.0.0.1:58988 failed:
java.net.SocketException: Connection reset
WARN | Transport
Connection to: tcp://127.0.0.1:58986 failed: java.net.SocketException:
Connection reset
Because the socket is implemented in activemq you would have to add the ExceptionListener there to write your own exception handling routine ...
Related
I have a consumer Java app which connects to an Apache ActiveMQ server. It's working. However, if I stop the Apache ActiveMQ server the consumer app has an exception:
java.net.SocketException: Connection reset
How can I handle this Exception, for example I'd like to send an alert e-mail to support. How can I detect offline ActiveMQ server.
Here is the exception details
// Getting JMS connection from the server
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(this.activeMqClient.getUsername(), this.activeMqClient.getPassword(), this.activeMqClient.getProducerUri());
activeMQConnectionFactory.setUseAsyncSend(false);
activeMQConnectionFactory.setMaxThreadPoolSize(1);
this.activeMqClient.setClientId(activeMqClient.getClientType() + "_" + Thread.currentThread().getName());
if (this.activeMqClient.getClientId() != null) {
activeMQConnectionFactory.setClientID(this.activeMqClient.getClientId());
}
Connection connection = activeMQConnectionFactory.createConnection();
if (this.activeMqClient.getClientId() != null) {
connection.setClientID(this.activeMqClient.getClientId());
}
connection.start();
connection.setExceptionListener(this);
// Creating session for receiving messages
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
// Getting the queue
Destination destination = session.createQueue(this.activeMqClient.getDestinationQueueName() + "?consumer.exclusive=true");
// MessageConsumer is used for receiving (consuming) messages
MessageConsumer consumer = session.createConsumer(destination);
//Setting message listener
consumer.setMessageListener(this);
You can catch it like any other exception:
try {
//... client code ...//
}
catch(SocketException e) {
//... send email ...//
}
I am using below code for connecting to JMS.I cannot create a connection factory because in PROD env, I am just a consumer and not aware which server it is installed. I have the broker URL,Username and Password.
public class HelloWorldProducer implements Runnable {
public void run() {
try {
// Create a ConnectionFactory
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("id972483","octitt123","tcp://ozoi6000:2506");
// Create a Connection
Connection connection = connectionFactory.createConnection();
connection.start();
// Create a Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the destination (Topic or Queue)
Destination destination = session.createQueue("gw.oct.request.letterbusinesscommunication.v1.in.q");
// Create a MessageProducer from the Session to the Topic or Queue
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// Create a messages
//String text = "Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode();
TextMessage message = session.createTextMessage(getXMLdata());
message.setJMSCorrelationID("Sample_JMS_Test");
// Tell the producer to send the message
System.out.println("Sent message: "+ message.hashCode() + " : " + Thread.currentThread().getName());
producer.send(message);
// Clean up
session.close();
connection.close();
}
catch (Exception e) {
System.out.println("Caught: " + e);
e.printStackTrace();
}
}
I am getting the error like below:
Caught: javax.jms.JMSException: Disposed due to prior exception
javax.jms.JMSException: Disposed due to prior exception
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:72)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1413)
at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1478)
at org.apache.activemq.ActiveMQConnection.start(ActiveMQConnection.java:527)
at HelloWorldProducer.run(HelloWorldProducer.java:25)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.activemq.transport.TransportDisposedIOException: Disposed due to prior exception
at org.apache.activemq.transport.ResponseCorrelator.onException(ResponseCorrelator.java:125)
at org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:114)
at org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:114)
at org.apache.activemq.transport.WireFormatNegotiator.onException(WireFormatNegotiator.java:173)
at org.apache.activemq.transport.AbstractInactivityMonitor.onException(AbstractInactivityMonitor.java:344)
at org.apache.activemq.transport.TransportSupport.onException(TransportSupport.java:96)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:219)
... 1 more
Caused by: java.io.IOException: Unknown data type: -1
at org.apache.activemq.openwire.OpenWireFormat.doUnmarshal(OpenWireFormat.java:359)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:278)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:240)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:232)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
... 1 more
What is configured on the port you are trying to connect to? You see these sorts of error when trying to connect the JMS client to a port that servicing a protocol other than the OpenWire protocol that the ActiveMQ JMS client speaks.
When getting errors like this it is usually a good idea to ask what the broker is actually configured to do
I am looking to extend AbstractJavaSamplerClient so that I can fire messages to RabbitMQ. The current setup I have is:
Have connection and channel objects as instance members
Create the connection and channel connection in setupTest()
Send the messages in runTest()
Clean up the connection in teardownTest()
Code:
package com.the.package.samplers.TheSampler
import ...
...
public final class TheSampler extends AbstractJavaSamplerClient {
private final ConnectionFactory factory = new ConnectionFactory();
private Connection connection = null;
private Channel channel = null;
...
#Override
public Arguments getDefaultParameters() {
Arguments parameters = new Arguments();
...
return parameters;
#Override
public void setupTest(JavaSamplerContext context) {
...
factory.setHost(host);
factory.setVirtualHost(vhost);
factory.setPort(port);
factory.setUsername(username);
factory.setPassword(password);
routingKey = queue;
try {
connection = factory.newConnection();
channel = connection.createChannel();
channel.exchangeDeclare(exchange, EXCHANGE_TYPE, true);
channel.queueDeclare(queue, true, false, false, null);
channel.queueBind(queue, exchange, routingKey);
}
catch(IOException e) {
...
}
}
#Override
public SampleResult runTest(JavaSamplerContext context) {
...
channel.basicPublish(exchange, routingKey, null, message.getBytes());
...
}
#Override
public void teardownTest(JavaSamplerContext context) {
try {
channel.close();
connection.close();
}
catch(IOException e) {
...
}
}
}
After running the JMeter test with 5 threads for some time, the message rate drops and I start seeing the following exception (repeated indefinitely):
ERROR - jmeter.threads.JMeterThread: Error while processing sampler 'Java Request' : com.rabbitmq.client.AlreadyClosedException: connection is already closed due to connection error; cause: java.net.SocketException: Connection reset
at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:190)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:291)
at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:647)
at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:630)
at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:621)
at com.the.package.samplers.TheSampler.runTest(TheSampler.java:102)
at org.apache.jmeter.protocol.java.sampler.JavaSampler.sample(JavaSampler.java:191)
at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:434)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:261)
at java.lang.Thread.run(Unknown Source)
I tried to be a bit more safe by creating and closing the connection and channel objects in runTest(), but that incurred a huge performance hit (fires at a max of 50 messages per second, and previously was in the thousands).
Is there a way to safely create a connection to RabbitMQ when extending AbstractJavaSamplerClient and running with multiple threads?
I don't see any issue in your code from what you show.
Where is JMeter located regarding rabbitmq server ? ie is there a firewall between them ?
You should check this:
https://www.rabbitmq.com/reliability.html
Detecting Dead TCP Connections with Heartbeats
I am trying to use ActiveMQ in a relatively simple work queue use case. I have one queue, and have a simple Producer and Consumer.
My question is what am I doing wrong that continuously makes the DB lock?
here is the message I get continously:
14/04/05 18:14:13 INFO store.SharedFileLocker: Database activemq-data\localhost\KahaDB\lock is locked... waiting 10 seconds for the database to be unlocked. Reason: java.io.IOException: File 'activemq-data\localhost\KahaDB\lock' could not be locked.
I am running the producer and consumer in separate threads at the same time.
Initially, I had the connection at the class level, so I thought that was the problem, but even creating the connection from scratch every call to put and get still causes locking.
I have done research but have failed to find a solution.
I am running ActiveMQ 5.9.0 on windows 7.
Here is what prints out when I start it via cmd prompt:
C:\activemq\apache-activemq-5.9.0\bin>activemq
Java Runtime: Oracle Corporation 1.7.0_40 C:\Program Files\Java\jre7
Heap sizes: current=1005568k free=995061k max=1005568k
JVM args: -Dcom.sun.management.jmxremote -Xms1G -Xmx1G -Djava.util.logging.config.file=logging.properties -Dhawtio.realm=activemq -Dhawtio.role=admins -Dhawtio.rolePrincipalCla
vemq.jaas.GroupPrincipal -Djava.security.auth.login.config=C:\activemq\apache-activemq-5.9.0\bin\..\conf\login.config -Dactivemq.classpath=C:\activemq\apache-activemq-5.9.0\bin\..\
che-activemq-5.9.0\bin\../conf;C:\activemq\apache-activemq-5.9.0\bin\../conf; -Dactivemq.home=C:\activemq\apache-activemq-5.9.0\bin\.. -Dactivemq.base=C:\activemq\apache-activemq-5
mq.conf=C:\activemq\apache-activemq-5.9.0\bin\..\conf -Dactivemq.data=C:\activemq\apache-activemq-5.9.0\bin\..\data -Djava.io.tmpdir=C:\activemq\apache-activemq-5.9.0\bin\..\data\t
Extensions classpath:
[C:\activemq\apache-activemq-5.9.0\bin\..\lib,C:\activemq\apache-activemq-5.9.0\bin\..\lib\camel,C:\activemq\apache-activemq-5.9.0\bin\..\lib\optional,C:\activemq\apache-activemq
b,C:\activemq\apache-activemq-5.9.0\bin\..\lib\extra]
ACTIVEMQ_HOME: C:\activemq\apache-activemq-5.9.0\bin\..
ACTIVEMQ_BASE: C:\activemq\apache-activemq-5.9.0\bin\..
ACTIVEMQ_CONF: C:\activemq\apache-activemq-5.9.0\bin\..\conf
ACTIVEMQ_DATA: C:\activemq\apache-activemq-5.9.0\bin\..\data
Loading message broker from: xbean:activemq.xml
INFO | Refreshing org.apache.activemq.xbean.XBeanBrokerFactory$1#5bf2a8f5: startup date [Sat Apr 05 17:42:42 EDT 2014]; root of context hierarchy
INFO | PListStore:[C:\activemq\apache-activemq-5.9.0\bin\..\data\localhost\tmp_storage] started
INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[C:\activemq\apache-activemq-5.9.0\bin\..\data\kahadb]
INFO | KahaDB is version 5
INFO | Recovering from the journal ...
INFO | Recovery replayed 6935 operations from the journal in 0.416 seconds.
INFO | Apache ActiveMQ 5.9.0 (localhost, ID:Owner-PC-49614-1396734165637-0:1) is starting
INFO | Listening for connections at: tcp://Owner-PC:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector openwire started
INFO | Listening for connections at: amqp://Owner-PC:5673?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector amqp started
INFO | Listening for connections at: stomp://Owner-PC:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector stomp started
INFO | Listening for connections at: mqtt://Owner-PC:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector mqtt started
INFO | Listening for connections at ws://Owner-PC:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector ws started
INFO | Apache ActiveMQ 5.9.0 (localhost, ID:Owner-PC-49614-1396734165637-0:1) started
INFO | For help or more information please see: http://activemq.apache.org
INFO | Welcome to hawtio 1.2-M23 : http://hawt.io/ : Don't cha wish your console was hawt like me? ;-)
INFO | Starting hawtio authentication filter, JAAS realm: "activemq" authorized role: "admins" role principal classes: "org.apache.activemq.jaas.GroupPrincipal"
INFO | Using file upload directory: C:\activemq\apache-activemq-5.9.0\bin\..\data\tmp\uploads
INFO | jolokia-agent: Using access restrictor classpath:/jolokia-access.xml
INFO | ActiveMQ WebConsole available at http://localhost:8161/
INFO | Initializing Spring FrameworkServlet 'dispatcher'
Here is my java to implement the Queue as ActiveMQ (I have a Queue interface and this is an Impl)
import com.google.gson.Gson;
import java.util.Set;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
public class ActiveMQImpl implements Queue, ExceptionListener {
private String host;
private String user;
private String pw;
public void init() {
}
public void close() {
}
public Message get() {
Message outMessage = null;
ActiveMQConnectionFactory connectionFactory = null;
Connection connection = null;
try {
if (connection == null) {
connectionFactory = new ActiveMQConnectionFactory("vm://localhost");
// Create a Connection
connection = connectionFactory.createConnection();
}
connection.start();
// Create a Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the destination (Topic or Queue)
Destination destination = session.createQueue("work");
// Create a MessageConsumer from the Session to the Topic or Queue
MessageConsumer consumer = session.createConsumer(destination);
// Wait for a message
javax.jms.Message message = consumer.receive(1000);
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
outMessage = new Gson().fromJson(text, Message.class);
// System.out.println("Received: " + text);
} else {
// System.out.println("Received: " + message);
}
consumer.close();
// session.commit();
session.close();
//connection.close();
} catch (Exception e) {
System.out.println("Caught: " + e);
e.printStackTrace();
}
return outMessage;
}
public void put(Message inMessage) {
try {
ActiveMQConnectionFactory connectionFactory = null;
Connection prodConnection = null;
connectionFactory = new ActiveMQConnectionFactory("vm://localhost");
prodConnection = connectionFactory.createConnection();
prodConnection.start();
Session session = prodConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("work");
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
producer.setTimeToLive(60000);
// Create a messages
String text = inMessage.toString();
TextMessage message = session.createTextMessage(text);
// Tell the producer to send the message
System.out.println("Sent message: " + text);
producer.send(message);
producer.close();
// session.commit();
session.close();
prodConnection.close();
} catch (Exception e) {
System.out.println("Caught: " + e);
onException(null);
e.printStackTrace();
}
}
public void onException(JMSException jmse) {
//send this to the error channel object...
System.out.println(jmse);
}
public void put(Set<Message> messages) {
try {
ActiveMQConnectionFactory connectionFactory=null;
Connection connection=null;
Connection prodConnection=null;
if (connection == null) {
connectionFactory = new ActiveMQConnectionFactory("vm://localhost?jms.useAsyncSend=true");
// Create a Connection
connection = connectionFactory.createConnection("admin", "admin");
}
connection.start();
// Create a Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the destination (Topic or Queue)
Destination destination = session.createQueue("work");
// Create a MessageProducer from the Session to the Topic or Queue
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
// Create a messages
for (Message inMessage : messages) {
String text = inMessage.toString();
TextMessage message = session.createTextMessage(text);
// Tell the producer to send the message
System.out.println("Sent message: " + text);
producer.send(message);
}
producer.close();
// session.commit();
session.close();
//connection.close();
} catch (Exception e) {
System.out.println("Caught: " + e);
onException(null);
e.printStackTrace();
}
}
}
Here are the producers and consumers (simple debugging classes)
public class Producer {
public static void main(String[] args) {
Queue q = QueueFactory.create(QueueType.ACTIVEMQ);
try {
for (int i = 0; i < 10; i++) {
q.put(new Message("testimpl" + i, "whatever", i));
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class Consumer {
public static void main(String[] args) {
Queue q = QueueFactory.create(QueueType.ACTIVEMQ);
try {
while (true) {
Message get = q.get();
System.out.println(get);
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
any help is appreciated.
do following
kill java process for active mq, open task manager -> go to process -> check for java -> and right click and say end process
then go to <activemq_install_directory>/data/kahadb
and delete lock file which gets generated
try starting activemq again
for me this works every time I face this issue
had the same problem.
there was no other java services / brokers up and running.
the problem was pretty stupid -
make sure that the user you are using has permission to write to the path of the lock file.
The only solution I came across to release this lock is-
Goto services.msc
Stop ActiveMQ forever (let StartUp type be Automatic)
you will see that the lock file disappears
delete the datafolder itself
Restart apache-activemq-5.10.0-bin\apache-activemq-5.10.0\bin\win64\activemq.bat (Not services.msc)
You are good to go
for linux just:
sudo killall java
and start again
EDIT: Rephrased the question:
I want to use ActiveMQ as a messenger service between my server and client applications.
I am trying to set up an embedded broker (i.e. not a separate process) within the server to handle the produced messages for my clients to consume. This queue is persisted.
The broker initialisation as follows:
BrokerService broker = new BrokerService();
KahaPersistenceAdapter adaptor = new KahaPersistenceAdapter();
adaptor.setDirectory(new File("activemq"));
broker.setPersistenceAdapter(adaptor);
broker.setUseJmx(true);
broker.addConnector("tcp://localhost:61616");
broker.start();
After tinkering, I ended up with the server part being:
public static class HelloWorldProducer implements Runnable {
public void run() {
try {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost"); // apparently the vm part is all i need
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("TEST.FOO");
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
String text = "Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode();
TextMessage message = session.createTextMessage(text);
System.out.println("Sent message: "+ message.hashCode() + " : " + Thread.currentThread().getName());
producer.send(message);
session.close();
connection.close();
}
catch (Exception e) {
System.out.println("Caught: " + e);
e.printStackTrace();
}
}
}
The client is very similar and looks like this:
public static class HelloWorldConsumer implements Runnable, ExceptionListener {
public void run() {
try {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost");
Connection connection = connectionFactory.createConnection(); // exception happens here...
connection.start();
connection.setExceptionListener(this);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("TEST.FOO");
MessageConsumer consumer = session.createConsumer(destination);
Message message = consumer.receive(1000);
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
System.out.println("*****Received: " + text);
} else {
System.out.println("*****Received obj: " + message);
}
consumer.close();
session.close();
connection.close();
} catch (Exception e) {
System.out.println("Caught: " + e);
e.printStackTrace();
}
}
The main method simply starts each of these in a thread to start producing/receiving messages.
...but I am running into the following with the start of each thread:
2013-01-24 07:54:31,271 INFO [org.apache.activemq.broker.BrokerService] Using Persistence Adapter: AMQPersistenceAdapter(activemq-data/localhost)
2013-01-24 07:54:31,281 INFO [org.apache.activemq.store.amq.AMQPersistenceAdapter] AMQStore starting using directory: activemq-data/localhost
2013-01-24 07:54:31,302 INFO [org.apache.activemq.kaha.impl.KahaStore] Kaha Store using data directory activemq-data/localhost/kr-store/state
2013-01-24 07:54:31,339 INFO [org.apache.activemq.store.amq.AMQPersistenceAdapter] Active data files: []
2013-01-24 07:54:31,445 DEBUG [org.apache.activemq.broker.jmx.ManagementContext] Probably not using JRE 1.4: mx4j.tools.naming.NamingService
2013-01-24 07:54:31,450 DEBUG [org.apache.activemq.broker.jmx.ManagementContext] Failed to create local registry
java.rmi.server.ExportException: internal error: ObjID already in use
at sun.rmi.transport.ObjectTable.putTarget(ObjectTable.java:186)
at sun.rmi.transport.Transport.exportObject(Transport.java:92)
at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:247)
at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:411)
at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:147)
<snip....>
It seems like the messages are produced and consumed successfully (the other issues I previously posted about was resolved), but the above exception is worrying me.
EDIT: During broker shutdown, I am now also greeted by the following:
2013-01-25 08:40:17,486 DEBUG [org.apache.activemq.transport.failover.FailoverTransport] Transport failed with the following exception:
java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:269)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:210)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:202)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:185)
at java.lang.Thread.run(Thread.java:722)
You can embed a broker into your code in a number of ways, much of which is documented here. You may want to try upgrading you version since what you are using appears to be quite old as it defaulting to the now deprecated AMQ Store instead of the newer KahaDB store. You might be having issues because of a race between the client threads as they use the different connection factories which could race to create in VM brokers. If you set the create=false option on the producer and ensure the consumer thread starts after that could address the issue, or you could create the VM broker ahead of time and the add create=false to both thread's and that might do the trick.
BrokerService broker = new BrokerService();
// configure the broker
broker.setBrokerName("localhost");
broker.setUseJmx(false);
broker.start();
And then in the client code just attach via this connection factory configuration.
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?create=false");
When I run your code, I got the below exception:
javax.jms.JMSException: Could not connect to broker URL: tcp://localhost.
Reason java.lang.IllegalArgumentException: port out of range:-1
Your broker is running and listening to port 61616, so any client which tries to connect to broker need to have the port in its URL.
The client code tries to connect to localhost but doesn't mention the port to which it has to connect.
Both the producer and consumer code needs to be fixed.
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost");
To
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
After fixing the port, I was able to run your code.