• Post Reply Bookmark Topic Watch Topic
  • New Topic

MessageConsumer.receive() hangs on ioexception

 
ray frid
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Using jboss 5.1, java standalone application.

I am trying to listen to messages from standalone application to jboss jms.

Problem is when I kill the jboss server I am getting an exception in the standalone application side but the receive() still hangs therefor my thread is stuck and i am not able to reconnect or do anything else.

thats the exception in my standalone:

2012-05-31 11:47:18,738 org.jboss.remoting.transport.socket.SocketClientInvoker [ERROR] Got marshalling exception, exiting
java.io.IOException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at java.io.DataOutputStream.flush(Unknown Source)
at org.jboss.jms.wireformat.SerializedPacket.write(SerializedPacket.java:81)
at org.jboss.jms.wireformat.JMSWireFormat.write(JMSWireFormat.java:237)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.versionedWrite(MicroSocketClientInvoker.java:971)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:606)
at org.jboss.remoting.transport.bisocket.BisocketClientInvoker.transport(BisocketClientInvoker.java:418)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
at org.jboss.remoting.ConnectionValidator.doCheckConnectionWithLease(ConnectionValidator.java:522)
at org.jboss.remoting.ConnectionValidator.run(ConnectionValidator.java:301)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
my standalone application code:

private static Logger log = LoggerFactory.getLogger(MomTopicListenerAbs.class);
protected String componentCode = null;
protected int reconnectTimeInterval = 30000;
MessageConsumer topicMsgConsumer = null;
Session topicSession = null;
String momUrl = null;
Connection topicConnection = null;
InitialContext jmsContext = null;
private Thread listenerThread = null;
boolean shouldListen = true;


@Override
public void connectToTopic() throws Exception
{
TopicConnectionFactory myConnFactory;
Topic myTopic;
String MYCF_LOOKUP_NAME = MomConstants.MOM_EXTERNAL_CONNECTION_FACTORY;
String MYTOPIC_LOOKUP_NAME = MomConstants.DISPATCHER_TOPIC_LOOKUP;
jmsContext = new InitialContext();
jmsContext.addToEnvironment("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
jmsContext.addToEnvironment("java.naming.factory.url.pkgs", "org.jnp.interfaces");
jmsContext.addToEnvironment(Context.PROVIDER_URL, momUrl);
myConnFactory = (javax.jms.TopicConnectionFactory) jmsContext.lookup(MYCF_LOOKUP_NAME);
myTopic = (Topic) jmsContext.lookup(MYTOPIC_LOOKUP_NAME);
topicConnection = myConnFactory.createConnection();
topicSession = topicConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topicMsgConsumer = topicSession.createConsumer(myTopic);
topicConnection.start();
}

@Override
public void run()
{
Message msg = null;
log.info("Listening to Mom Topic at url=" + momUrl + " started.");
try
{

connectToTopic();
while (shouldListen)
{
try
{ //this is where it hangs when I kill the jboss server.
msg = topicMsgConsumer.receive();
if (msg == null)
{
throw new Exception("Received empty msg from Topic Listener. could be caused by stopListening() invoke");
}
executeMsgThread(msg);
}
catch (JMSException e)
{
log.error("Caught JMS exception, reconnecting...", e);
}
catch (Exception e)
{
log.error("Error in topic Listener. errorMsg=" + e.getMessage(), e);
}
}
}
catch (Throwable t)
{
log.error(TAG + ", System error", t);
}
How will I be able to catch that exception?

thanks, ray.
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The specs for receive say that This call blocks indefinitely until a message is produced or until this message consumer is closed.
So maybe try receive(timeout) depending on your requirements.
 
ray frid
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A timeout wont help me since in a regular situation I need that receive() method to wait for a messages. and in case of disoconnection like this I need to reconnect but I cant since the receive() hangs.
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In regular situation the receive will still wait for the message. It just won't block forever. Your while(true) loop will take care of the 'reconnection'.
 
ray frid
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well that could solve this issue. what I do afraid if a message will come while it disconnects and reconnects.. then it will be lost..
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Message won't be lost for that reason because the consumer is still open so the connection is not actually closed.
 
ray frid
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I thought about it. the message will be lost because each time I will get timeout I will need to reconnect to the Topic. if the server is went down in the middle of my receive I will need to reconnect to it.
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ray frid wrote:Hi,
I thought about it. the message will be lost because each time I will get timeout I will need to reconnect to the Topic. if the server is went down in the middle of my receive I will need to reconnect to it.

JMS guarantees that messages are not lost on server crash if they are not acknowledged (except for a few corner cases to be clarified with JMS 2).
Your problem here is just in letting the client detect a server crash and attempt reconnection when the server starts up.
Look at using the canConnect method and maybe do an incrementally delayed while loop until canConnect returns true before proceeding to the receive loop. If receive times out go back to the canConnect loop.
 
ray frid
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You mention canConnect method. on which object are you talking about? could you show simple example of your meaning..?

thanks,
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ray frid wrote:You mention canConnect method. on which object are you talking about? could you show simple example of your meaning..?

thanks,

My bad "Look at using the canConnect" was supposed to be "Look at using a canConnect" so you'd have to write one yourself.
Make sure the canConnect method reinitializes all objects. You can make it wait for an incrementing period for each failure and put alerting for each failure.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!