Author |
Message
|
smalltalk2k |
Posted: Thu Jun 16, 2005 5:09 am Post subject: Problem with JMS/MQ leaving open connections - code inside. |
|
|
Novice
Joined: 03 May 2005 Posts: 10
|
I'm having a problem with my jms recieving code on leaving 3 open connections. No exceptions are being thrown and I checked my debug logs and all of the closing log statements are being out put. So the .close() commands are being issued. However when I run netstat from the command line 3 connections are still open and on the MQ series server the MQ admin shows that 3 connections are still open from my IP address.
I'm running WSAD 5.1.2 , the JMS server is running mq 5.3
My context provider is (copied from my properties file): JMS_TEST7.CONTEXT_FACTORY=com.ibm.mq.jms.context.WMQInitialContextFactory
I have the com.ibm.mq.pcf.jar file in my /lib
I also have mqcontext.jar in my /lib
It is set up as a thread and it only starts up one time. I start the listener up in a servlet and it runs until a web page sends it the command to stop. However it stops fine with no exceptions but the connections appear to not actually be closing.
I don't have the Jms resource set up in WSAD as a resource. I directly connect to the MQ server. Since at one time there will be just one listener running, as it is a singleton.
If you need any more info that I can provide that will help let me know.
--
there is a line below "receiver = null;" I've ran the program both with and without this line and the result is the same.
--
the code is:
Code: |
package com.xx.fsa.mq;
import com.xx.fsa.tools.CTCSActivityMessageHandler;
import com.xx.fsa.tools.CTCSWebLog;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.jms.ConnectionMetaData;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.log4j.Logger;
/*
* Created on Jul 30, 2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
/**
* @author
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class FieldServer7Reciever extends Thread {
static Logger log = Logger.getLogger(CTCSWebLog.class.getName());
private boolean running = false;
private static final class SingletonHolder {
static final FieldServer7Reciever _singleton =
new FieldServer7Reciever();
}
private FieldServer7Reciever() {
}
public static FieldServer7Reciever getInstance() {
return SingletonHolder._singleton;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
//public static void main(String[] args) {}
public void run() {
markRunning();
String queueName = null;
InitialContext context = null;
QueueConnectionFactory qcf = null;
QueueConnection conn = null;
QueueSession session = null;
Queue q = null;
QueueReceiver receiver = null;
TextMessage message = null;
try {
String icf = Messages.getString("JMS_TEST7.CONTEXT_FACTORY"); //$NON-NLS-1$
String url = Messages.getString("JMS_TEST7.URL"); //$NON-NLS-1$
// Initialise JNDI properties
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, icf);
env.put(Context.PROVIDER_URL, url);
context = new InitialContext(env);
// Lookup the queue connection factory from the
// initial context.
qcf = (QueueConnectionFactory) context.lookup(Messages.getString("JMS_TEST7.SERVER_NAME")); //$NON-NLS-1$
// Create a new queue connection from the queue
// connection factory.
conn = qcf.createQueueConnection();
// Create a new queue session from the queue
// connection. The session should be transacted
session = conn.createQueueSession(true, -1);
// Lookup the queue to be used to send and receive
// messages from the initial context.
q = (Queue) context.lookup(Messages.getString("JMS_TEST7.QUEUE_NAME")); //$NON-NLS-1$
// Create a new queue receiver using the queue session.
// The queue receiver should be created to receive
// messages from the queue q.
receiver = session.createReceiver(q);
// Start the connection
conn.start();
log.debug(Messages.getString("JMS_TEST7.MESSAGE_CONNECTED")); //$NON-NLS-1$
// Use the queue receiver to receive the message that
// was sent previously.
log.debug(Messages.getString("JMS_TEST7.MESSAGE_LISTENER_STARTED")); //$NON-NLS-1$
boolean dbSuccess = true;
printJMS_Info(conn.getMetaData());
while (isRunning() ) {
//dbtest();
log.debug("FieldServer 7 checking for messages...");
dbSuccess = true;
Message m = receiver.receive(5000);
if (m != null) {
if (m instanceof TextMessage) {
message = (TextMessage) m;
log.debug(
"FieldServer 7 Message: " + message.getText());
dbSuccess =
CTCSActivityMessageHandler.handleMessage(message);
if (dbSuccess) {
log.debug("FieldServer 7 COMMITING JMS");
session.commit();
} else {
log.debug("FieldServer 7 ROLLING BACK JMS");
session.rollback();
}
} else {
log.debug(Messages.getString("JMS_TEST7.MESSAGE_NON_TEXT_RECIEVED")); //$NON-NLS-1$
stopLoop();
log.debug("FieldServer 7 COMMITING JMS");
session.commit();
}
} else {
// commit the null message
log.debug("FieldServer 7 COMMITING JMS");
session.commit();
}
//yield();
}
} catch (NamingException ne) {
try {
log.debug("FieldServer 7 ROLLING BACK JMS");
session.rollback();
} catch (Exception ex1) {
log.warn(this, ex1);
}
log.warn(this, ne);
} catch (JMSException jmse) {
try {
log.debug("FieldServer 7 ROLLING BACK JMS");
session.rollback();
} catch (Exception ex1) {
log.warn(this, ex1);
}
Exception linkedException = jmse.getLinkedException();
if (linkedException != null) {
log.warn(this, linkedException);
}
log.warn(this, jmse);
} catch (Exception exc) {
try {
log.debug("FieldServer 7 ROLLING BACK JMS");
session.rollback();
} catch (Exception ex1) {
log.warn(this, ex1);
}
log.warn(this, exc);
} finally {
stopLoop();
if (conn != null) {
try {
log.debug(Messages.getString("JMS_TEST7.MESSAGE_CLOSING_CONNECTION")); //$NON-NLS-1$
conn.stop();
receiver.close();
receiver = null;
session.close();
conn.close();
log.debug(Messages.getString("JMS_TEST7.MESSAGE_CLOSED_CONNECTION")); //$NON-NLS-1$
} catch (JMSException e) {
log.warn(this, e);
}
}
}
}
private void printJMS_Info(ConnectionMetaData md){
try {
log.debug("JMS MAJOR VERSION: " + md.getJMSMajorVersion());
log.debug("JMS MINOR VERSION: " + md.getJMSMinorVersion());
log.debug("JMS PROVIDER NAME: " + md.getJMSProviderName());
log.debug("JMS VERSION: " + md.getJMSVersion());
log.debug("JMS PROVIDER MAJOR VERSION: " + md.getProviderMajorVersion());
log.debug("JMS PROVIDER MINOR VERSION: " + md.getProviderMinorVersion());
log.debug("JMS PROVIDER VERSION: " + md.getProviderVersion());
Enumeration enumeration = md.getJMSXPropertyNames();
while (enumeration.hasMoreElements()) {
String element = (String) enumeration.nextElement();
log.debug("JMSX PROPERTY NAME: "+ element);
}
} catch (Exception e) {
log.debug(this, e);
}
}
public void stopLoop() {
log.debug("Field Server 7 Activity Tracking Listener marked for STOP");
running = false;
}
private void stopLoop(boolean flag) {
running = flag;
}
public boolean isStopped() {
return !running;
}
public boolean isRunning() {
return running;
}
private void markRunning() {
running = true;
}
}
|
|
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Jun 16, 2005 5:24 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Does the JVM completely shut down when this program ends?
I have seen MQ connections stay open in Java for at least a period of time after they have been closed and discarded.
Also check the KeepAlive on your svrconn channels. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
smalltalk2k |
Posted: Thu Jun 16, 2005 5:37 am Post subject: |
|
|
Novice
Joined: 03 May 2005 Posts: 10
|
jefflowrey wrote: |
Does the JVM completely shut down when this program ends?
I have seen MQ connections stay open in Java for at least a period of time after they have been closed and discarded.
Also check the KeepAlive on your svrconn channels. |
It is run as a web app. So the JVM only ends when the server is terminated. When the server terminates then the connections will finally end. I have to get with the MQ admin but I think he recieves an error when I shut down my web app server. I'll try to get the actual MQ log error he gets.
scenario:
I start the listener.
I stop the listener thread(the close() commands complete)
- the connection remain open -
5, 10, or 15 minutes later i shut down my app server
when my app server terminates the mq admin says he sees a error on his log - i'll post it when he comes in today.
= edit =
here is some excerpts from my log files...
DEBUG FieldServer7Reciever - JMS MAJOR VERSION: 1
DEBUG FieldServer7Reciever - JMS MINOR VERSION: 0
DEBUG FieldServer7Reciever - JMS PROVIDER NAME: IBM
DEBUG FieldServer7Reciever - JMS VERSION: 1.0
DEBUG FieldServer7Reciever - JMS PROVIDER MAJOR VERSION: 5
DEBUG FieldServer7Reciever - JMS PROVIDER MINOR VERSION: 300
DEBUG FieldServer7Reciever - JMS PROVIDER VERSION: 5.300
DEBUG FieldServer7Reciever - JMSX PROPERTY NAME: JMSXUserID
DEBUG FieldServer7Reciever - JMSX PROPERTY NAME: JMSXAppID
DEBUG FieldServer7Reciever - JMSX PROPERTY NAME: JMSXDeliveryCount
DEBUG FieldServer7Reciever - JMSX PROPERTY NAME: JMSXGroupID
DEBUG FieldServer7Reciever - JMSX PROPERTY NAME: JMSXGroupSeq
...
here it is listening and then you can see a stop command is issued...
DEBUG FieldServer7Reciever - FieldServer 7 checking for messages...
DEBUG FieldServer7Reciever - FieldServer 7 COMMITING JMS
DEBUG FieldServer7Reciever - FieldServer 7 checking for messages...
DEBUG FieldServer7Reciever - FieldServer 7 COMMITING JMS
DEBUG FieldServer7Reciever - FieldServer 7 checking for messages...
---- THE WEB PAGE STOP COMMAND HERE BETWEEN THESE NOTES---
[6/16/05 8:39:31:143 CDT] 35d4f02d WebGroup I SRVE0180I: [CTCS_WEB] [/CTCS_WEB] [Servlet.LOG]: Session is null Redirecting from [/CTCS_WEB/QueryMQListener.do] to [index.jsp]
---- THE WEB PAGE STOP COMMAND HERE BETWEEN THESE NOTES---
DEBUG FieldServer7Reciever - Field Server 7 Activity Tracking Listener marked for STOP
DEBUG FieldServer7Reciever - FieldServer 7 COMMITING JMS
DEBUG FieldServer7Reciever - Field Server 7 Activity Tracking Listener marked for STOP
DEBUG FieldServer7Reciever - >> Closing FieldServer7 Listener Connection
DEBUG FieldServer7Reciever - >> FieldServer7 Listener Connection Closed |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Jun 16, 2005 1:57 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Your app looks nice and closes everything.
Now for the BIG question. Do you have any MDB defined listening to a queue?
As long as the MDB service is running you will have at least one connection to the qmgr. You will not be able to restart the qmgr until that process has shut down or is killed (in case of a bindings connection)....
Enjoy  |
|
Back to top |
|
 |
andyho |
Posted: Thu Jun 16, 2005 8:49 pm Post subject: |
|
|
Newbie
Joined: 19 Oct 2004 Posts: 2
|
Please note that all JDBC, MQ connection is from a connection pool.
So, when you close it, it just return to the pool. Nothing is really closed. |
|
Back to top |
|
 |
malammik |
Posted: Fri Jun 17, 2005 7:07 am Post subject: |
|
|
 Partisan
Joined: 27 Jan 2005 Posts: 397 Location: Philadelphia, PA
|
|
Back to top |
|
 |
smalltalk2k |
Posted: Mon Jun 20, 2005 5:24 am Post subject: |
|
|
Novice
Joined: 03 May 2005 Posts: 10
|
to start the listener I use this code.
Code: |
FieldServer7Reciever.getInstance().start(); |
to stop it i call.
Code: |
FieldServer7Reciever.getInstance().stopLoop();
|
There are only 2 classes in my web app that uses JMS/MQ, and they are duplicates of each other except one classes connects to a server named server7 and other connects to a server called server 8. The tests I've been running are just where one (server 7) is running. In my tests I never start the server 8 listener. The calling code is in a Struts/Tiles action. complete code below. In the code below you see a wait(3000), this is just in there to ensure that the struts action doesn't return before the actual listener stops or starts successfully, as the web page checks the listener to see if it is running, or stopped. but then that shouldn't affect the listener closing connections as far as I know, since the disconnects are successfully being called.
I ran another test and ever after 2 hours the connections remain open until I actually terminate my test server. In the listener in the method CTCSActivityMessageHandler.handleMessage(message); some database access occurs. But that shouldn't affect the mq/jms stuff. The database server is on a totally different server than the MQ qmanagers.
I ran a pooling test also. I started the listener and 3 connections were open, I stopped the listener, waited 10 minutes, 3 connections still open. I restarted the listener using the code you see here. 6 connections were open then. So the connection count went up.
Code: |
package com.xx.fsa.communications.strutsaction;
import com.xx.fsa.communications.strutsform.MQListenerActionForm;
import com.xx.fsa.mq.FieldServer7Reciever;
import com.xx.fsa.mq.FieldServer8Reciever;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.tiles.actions.TilesAction;
/** @modelguid {100D8B18-972D-44FF-AE03-D6EAE446CD83} */
public class MQListenerQueryAction extends TilesAction {
static Logger log = Logger.getLogger(MQListenerQueryAction.class.getName());
/** @modelguid {0EE9D420-9B21-470E-8CCB-77C8DDFFB741} */
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest req,
HttpServletResponse res) {
MQListenerActionForm myForm = (MQListenerActionForm) form;
performAction(myForm);
myForm.setStart7SubmitButton(null);
myForm.setStart8SubmitButton(null);
myForm.setStop7SubmitButton(null);
myForm.setStop8SubmitButton(null);
myForm.setRefreshStatusButton(null);
return (mapping.findForward("success"));
}
private synchronized void performAction(MQListenerActionForm form) {
try {
if (form.getStart7SubmitButton() != null) {
if (!FieldServer7Reciever.getInstance().isRunning()) {
FieldServer7Reciever.getInstance().start();
}
}
if (form.getStart8SubmitButton() != null) {
if (!FieldServer8Reciever.getInstance().isRunning()) {
FieldServer8Reciever.getInstance().start();
}
}
if (form.getStop7SubmitButton() != null) {
if (FieldServer7Reciever.getInstance().isRunning()) {
FieldServer7Reciever.getInstance().stopLoop();
}
}
if (form.getStop8SubmitButton() != null) {
if (FieldServer8Reciever.getInstance().isRunning()) {
FieldServer8Reciever.getInstance().stopLoop();
}
}
wait(3000);
} catch (Exception e) {
// TODO Auto-generated catch block
log.error(this, e);
}
}
}
|
Last edited by smalltalk2k on Mon Jun 20, 2005 7:00 am; edited 1 time in total |
|
Back to top |
|
 |
smalltalk2k |
Posted: Mon Jun 20, 2005 6:52 am Post subject: |
|
|
Novice
Joined: 03 May 2005 Posts: 10
|
I just got the MQ server side error messages from the admin.
this error happens on his end when I terminate my web server.
These errors are if my list is correct, 'connection reset by peer' errors.
I mentioned the jar files i'm using in the original post but I have the actual IBM support pac numbers now that I am using.
Support pacs:
ME01 and MS0B.
Here is some excerpts from my .classpath file in WSAD.
<classpathentry kind="var" path="WAS_50_PLUGINDIR/mqjms/Java/lib/com.ibm.mq.jar"/>
<classpathentry kind="var" path="WAS_50_PLUGINDIR/mqjms/Java/lib/com.ibm.mqbind.jar"/>
<classpathentry kind="var" path="WAS_50_PLUGINDIR/mqjms/Java/lib/com.ibm.mqjms.jar"/>
<classpathentry kind="lib" path="WebContent/WEB-INF/lib/mqcontext.jar"/>
<classpathentry kind="lib" path="WebContent/WEB-INF/lib/com.ibm.mq.pcf.jar"/>
Code: |
06/20/2005 09:11:18
AMQ9208: Error on receive from host 165.xxx.xx.xx.
EXPLANATION:
An error occurred receiving data from 165.xxx.xx.xx over TCP/IP. This may be
due to a communications failure.
ACTION:
The return code from the TCP/IP (recv) call was 10054 (X'2746'). Record these
values and tell the systems administrator.
----- amqccita.c : 2761 -------------------------------------------------------
06/20/2005 09:11:18
AMQ9208: Error on receive from host 165.xxx.xx.xx.
EXPLANATION:
An error occurred receiving data from 165.xxx.xx.xx over TCP/IP. This may be
due to a communications failure.
ACTION:
The return code from the TCP/IP (recv) call was 10054 (X'2746'). Record these
values and tell the systems administrator.
----- amqccita.c : 2761 ----------------------------------------------------
|
|
|
Back to top |
|
 |
teal |
Posted: Wed Jun 22, 2005 12:30 pm Post subject: |
|
|
 Acolyte
Joined: 15 Dec 2004 Posts: 66
|
I have the exact same issue. I have a MDB (50 max connections) and 10 other MDB that are serialized (1 max conn) I noticed that it always leaves the open input to the max numbers. I am closing my connections/sessions also but this only returns the connection to the pool.
Intersting..what did you mean Jeff by:
Quote: |
Also check the KeepAlive on your svrconn channels. |
I do have keepalive=yes in my qm.ini but I only want Sender/Receivers to use keep alive.
the KAINT(auto) and HBINT(300) in SVRCONN display channel,
the bottom line is I want this open input count to go down as the connection pool does but WAS is holding onto these MQ SVRconn connections for each Queue ConnectionFactory |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Jun 22, 2005 3:48 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Read the JMS Topology paper from the ibm site. |
|
Back to top |
|
 |
teal |
Posted: Sat Sep 03, 2005 8:13 am Post subject: |
|
|
 Acolyte
Joined: 15 Dec 2004 Posts: 66
|
thanks for the topology reference, it is good.
But can you elaborate on what you said Jeff?
Quote: |
Also check the KeepAlive on your svrconn channels. |
|
|
Back to top |
|
 |
jgray |
Posted: Thu Sep 08, 2005 9:24 am Post subject: question |
|
|
Newbie
Joined: 07 Sep 2005 Posts: 8 Location: nyc
|
can you check and see how many connections exist before and after the:
context = new InitialContext(env);
line? i don't know what your initialcontext class does, but in the me01 support pac for mq, the WMQinitialcontextfactory establishes one connection to the qmgr to look for queue definitions and another to the system admin queue to get the actual connectionfactory objects and then ANOTHER connection is established when i connect to my queue. i have to do a context.close() after i get my qcf in order to close the first two connections established by my initialcontextfactory. hope this helps & good luck. |
|
Back to top |
|
 |
|