Messaging client hangs on exit
peterj Sep 10, 2006 8:00 PMI have a simple messaging client that opens a topic as both a subcriber and publisher, with a listener on the subscriber. Once I send and receive one message on the topic, the program hangs when I try to exit. I know that there must be something I am doing wrong but cannot see it.
Particulars: JBoss AS 4.0.4.GA, JBoss Messaging 1.0.1.CR3, JDK 1.5.0_06
Here is my code:
package jms; import java.io.BufferedReader; import java.io.InputStreamReader; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import javax.jms.TopicConnection; import javax.jms.TopicConnectionFactory; import javax.jms.TopicPublisher; import javax.jms.TopicSession; import javax.jms.TopicSubscriber; import javax.naming.InitialContext; public class Echo implements javax.jms.MessageListener { private TopicSession sessionPublisher; private TopicSession sessionSubscriber; private TopicPublisher publisher; private TopicSubscriber subscriber; private TopicConnection connection; public Echo() throws Exception { InitialContext jndi = new InitialContext(); TopicConnectionFactory factory = (TopicConnectionFactory)jndi.lookup("ConnectionFactory"); connection = factory.createTopicConnection(); sessionPublisher = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); sessionSubscriber = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); Topic topic = (Topic)jndi.lookup("topic/testTopic"); publisher = sessionPublisher.createPublisher(topic); subscriber = sessionSubscriber.createSubscriber(topic); subscriber.setMessageListener(this); connection.start(); } public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage)message; String text = textMessage.getText(); System.out.println("echo: " + text); } catch (JMSException e) { e.printStackTrace(); } } protected void writeMessage(String text) throws JMSException { TextMessage message = sessionPublisher.createTextMessage(); message.setText(text); publisher.publish(message); } public void close() throws JMSException { connection.close(); } public static void main(String[] args) throws Exception { Echo echo = new Echo(); BufferedReader commandLine = new java.io.BufferedReader(new InputStreamReader(System.in)); boolean looping = true; System.out.println("Echo chamber is ready..."); while (looping) { String s = commandLine.readLine(); if (s.equals("q")) { looping = false; } else echo.writeMessage(s); } echo.close(); System.out.println("Good-bye!"); } }
Here is the output for an example run, followed by a thread dump:
>java ... jms.Echo log4j:WARN No appenders could be found for logger (org.jboss.remoting.transport. socket.SocketClientInvoker). log4j:WARN Please initialize the log4j system properly. Echo chamber is ready... hello echo: hello q Good-bye! Full thread dump Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode): "DestroyJavaVM" prio=6 tid=0x00036fa8 nid=0x114c waiting on condition [0x0000000 0..0x0007fae8] "SocketServerInvokerThread-192.168.0.101-0" prio=6 tid=0x0ae4fc50 nid=0x16ac run nable [0x0b48f000..0x0b48fae8] at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at java.io.BufferedInputStream.fill(Unknown Source) at java.io.BufferedInputStream.read(Unknown Source) - locked <0x02b520b0> (a java.io.BufferedInputStream) at java.io.FilterInputStream.read(Unknown Source) at org.jboss.serial.io.JBossObjectInputStream.read(JBossObjectInputStrea m.java:193) at org.jboss.remoting.transport.socket.ServerThread.readVersion(ServerTh read.java:497) at org.jboss.remoting.transport.socket.ServerThread.processInvocation(Se rverThread.java:414) at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.j ava:534) at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.jav a:257) "Timer-0" daemon prio=6 tid=0x0ae4d998 nid=0xda0 in Object.wait() [0x0b44f000..0 x0b44fb68] at java.lang.Object.wait(Native Method) - waiting on <0x030d3ce0> (a java.util.TaskQueue) at java.lang.Object.wait(Unknown Source) at java.util.TimerThread.mainLoop(Unknown Source) - locked <0x030d3ce0> (a java.util.TaskQueue) at java.util.TimerThread.run(Unknown Source) "GC Daemon" daemon prio=2 tid=0x0ac83120 nid=0x1374 in Object.wait() [0x0af4f000 ..0x0af4fd68] at java.lang.Object.wait(Native Method) - waiting on <0x02fe8a08> (a sun.misc.GC$LatencyLock) at sun.misc.GC$Daemon.run(Unknown Source) - locked <0x02fe8a08> (a sun.misc.GC$LatencyLock) "RMI RenewClean-[192.168.0.101:1098]" daemon prio=6 tid=0x0ac8a578 nid=0x1174 in Object.wait() [0x0af0f000..0x0af0f9e8] at java.lang.Object.wait(Native Method) - waiting on <0x02fe8a70> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) - locked <0x02fe8a70> (a java.lang.ref.ReferenceQueue$Lock) at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(Unknow n Source) at java.lang.Thread.run(Unknown Source) "Low Memory Detector" daemon prio=6 tid=0x00a92b20 nid=0x1154 runnable [0x000000 00..0x00000000] "CompilerThread0" daemon prio=10 tid=0x00a91820 nid=0x10bc waiting on condition [0x00000000..0x0abcf84c] "Signal Dispatcher" daemon prio=10 tid=0x00a90a18 nid=0x10b4 waiting on conditio n [0x00000000..0x00000000] "Finalizer" daemon prio=8 tid=0x00a87a30 nid=0x11b8 in Object.wait() [0x0ab4f000 ..0x0ab4fc68] at java.lang.Object.wait(Native Method) - waiting on <0x02fc4768> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) - locked <0x02fc4768> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source) "Reference Handler" daemon prio=10 tid=0x00a86598 nid=0x1514 in Object.wait() [0 x0ab0f000..0x0ab0fce8] at java.lang.Object.wait(Native Method) - waiting on <0x02fc47e8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Unknown Source) at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source) - locked <0x02fc47e8> (a java.lang.ref.Reference$Lock) "VM Thread" prio=10 tid=0x00a823f8 nid=0x1144 runnable "VM Periodic Task Thread" prio=10 tid=0x00a90958 nid=0xa0c waiting on condition
I also tried, in the Echo.close() method, to close the various sessions, unset the listener, and a few other variations to no avail. It appears as if the listener is still active, even after the connection is closed.
I did try ending the program with System.exit(0), and that worked, but calling System.exit() should be only a last ditch effort to bring the JVM down, not the normal way of exiting an application.