Author |
Message
|
jstorni |
Posted: Wed Jul 26, 2006 7:21 am Post subject: Connections are not released (Servlet and Java MQ API) |
|
|
Novice
Joined: 03 Feb 2006 Posts: 10
|
Hi all,
I'm a developer and don't have responses for this problem. For sure, you MQ Administrators guys will know this.
The scenario: a sample servlet that create 10 connections to the same queue manager in the init() method, and release them in the destroy() method. So when the application is started, 10 connections are created and when the application is stopped, the connections are closed. This is a very simplistic example created to show the problem that we have with our real application. We are running the servlet in a WAS 5.1 and connecting to a MQ 5.3 in the same Linux box (Red Hat enterprise on a AMD 64 bits machine).
The problem: after the application is stopped, the connections seems to remain active. We checked that with the netstat -an command and the TCP/IP connections still appear ESTABLISHED. These connections (at least at TCP/IP level) are released after the WAS instance is stopped.
The servlet code:
Code: |
import java.io.IOException;
import java.util.Hashtable;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ibm.mq.MQC;
import com.ibm.mq.MQException;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
public class ConnectionTest extends HttpServlet implements Servlet {
MQQueueManager[] qmgrs = new MQQueueManager[10];
MQQueue[] qRequests = new MQQueue[10];
Hashtable myProps = new Hashtable();
protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {}
protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {}
public void init(ServletConfig arg0) throws ServletException {
System.out.println("Connecting");
myProps.put(MQC.HOST_NAME_PROPERTY, "localhost");
myProps.put(MQC.PORT_PROPERTY, new Integer(1414));
myProps.put(MQC.CHANNEL_PROPERTY, "SYSTEM.DEF.SVRCONN");
/* Open 10 connections to the same queue manager and open 10 times the same queue */
for (int n=0; n < 10; n++) {
MQQueueManager qmgr = null;
MQQueue qRequest = null;
try {
qmgr = new MQQueueManager("TEST_QUEUE_MANAGER",myProps);
qRequest = qmgr.accessQueue("TEST_QUEUE",
MQC.MQOO_FAIL_IF_QUIESCING + MQC.MQOO_OUTPUT);
} catch (MQException e) {
e.printStackTrace();
}
qmgrs[n] = qmgr;
qRequests[n] = qRequest;
}
}
public void destroy() {
/* Close each queue
* Close and disconnect each queue manager
*/
for (int n=0; n < 10; n++) {
try {
qRequests[n].close();
qmgrs[n].close();
qmgrs[n].disconnect();
} catch (MQException e) {
e.printStackTrace();
}
}
System.out.println("Disconnected");
}
}
|
Any idea ?
Thanks in advance.
Javier Storni
[/code] |
|
Back to top |
|
 |
bower5932 |
Posted: Wed Jul 26, 2006 7:33 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Aug 2001 Posts: 3023 Location: Dallas, TX, USA
|
What version of WMQ are you using? I believe there was a problem similar to this fixed in one of the early CSDs. |
|
Back to top |
|
 |
jstorni |
Posted: Wed Jul 26, 2006 7:39 am Post subject: |
|
|
Novice
Joined: 03 Feb 2006 Posts: 10
|
bower5932 wrote: |
What version of WMQ are you using? I believe there was a problem similar to this fixed in one of the early CSDs. |
We are using WMQ 5.3.
If this is a previously reported problem, could you provide me a link to it or some details about it ?
Many (many) thanks in advance.
Regards
Javier Storni |
|
Back to top |
|
 |
bower5932 |
Posted: Wed Jul 26, 2006 9:12 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Aug 2001 Posts: 3023 Location: Dallas, TX, USA
|
jstorni wrote: |
We are using WMQ 5.3. |
With or without a CSD applied? |
|
Back to top |
|
 |
jstorni |
Posted: Wed Jul 26, 2006 11:39 am Post subject: |
|
|
Novice
Joined: 03 Feb 2006 Posts: 10
|
bower5932 wrote: |
jstorni wrote: |
We are using WMQ 5.3. |
With or without a CSD applied? |
CSD12
Many thanks.
Javier Storni |
|
Back to top |
|
 |
wschutz |
Posted: Wed Jul 26, 2006 11:48 am Post subject: |
|
|
 Jedi Knight
Joined: 02 Jun 2005 Posts: 3316 Location: IBM (retired)
|
Why are you doing this?
Have you tried without that close (leaving the MQQueue close())? _________________ -wayne |
|
Back to top |
|
 |
jstorni |
Posted: Wed Jul 26, 2006 12:14 pm Post subject: |
|
|
Novice
Joined: 03 Feb 2006 Posts: 10
|
wschutz wrote: |
Why are you doing this?
Have you tried without that close (leaving the MQQueue close())? |
I've commented that line without any result.
Is this common ? I'm very surprised about this. From the "command line", that is a J2SE application, the same code works perfectly.
Are there any relation between WAS and some "session" state of the MQ api ?
Many thanks
Javier Storni |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Jul 26, 2006 12:24 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
What happens if you run your code as a standalone j2se app, but do *not* stop the JVM after you've destroyed your object?
In other words, use a main routine that never quits, but creates, exercises, and then destroys an object of your class that makes MQ connections?
In other words, can you demonstrate that this behavior occurs as long as the JVM is running?
Also, is your WAS on the same machine as the qmgr? Or a different one? If on a different one, make sure that the MQ Client is also at 5.3 FP12. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
jstorni |
Posted: Wed Jul 26, 2006 12:33 pm Post subject: |
|
|
Novice
Joined: 03 Feb 2006 Posts: 10
|
jefflowrey wrote: |
What happens if you run your code as a standalone j2se app, but do *not* stop the JVM after you've destroyed your object?
In other words, use a main routine that never quits, but creates, exercises, and then destroys an object of your class that makes MQ connections?
In other words, can you demonstrate that this behavior occurs as long as the JVM is running?
Also, is your WAS on the same machine as the qmgr? Or a different one? If on a different one, make sure that the MQ Client is also at 5.3 FP12. |
I perfectly understand..... that was the first test. Run the same code as a J2SE application, and test if the program closes the connections before the VM instance finishes. In that mode, the program runs ok.
That's our concern !! What is the difference ? As you can see, we are lost.
The manager is running in the same box than the application. We are using the standard MQ jars for connectivity. I don't know if these jars have fixpacks applied. I'm going to check that.
Do you think if there are any relation with some "keep alive time" of the OS or the MQ server ?
Many thanks.
Javier Storni |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Jul 26, 2006 1:15 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
As long as you're pointing the MQ_INSTALL_ROOT and MQ_JAVA_LIB (or whatever it's called?) WAS environment variables at the MQ install directory, then you should be using versions of the MQ jars that are at the CSD12 level.
If you've done anything funny with classloaders or putting jar files into EAR files or etc, then you might be pointing at older versions of the MQ classes, and this could be causing your problem.
If you haven't adjusted MQ_INSTALL_ROOT, and didn't install WAS *after* you installed MQ, then you might also be pointing at older versions of the MQ jar files.
If it were an issue with KeepAlive on the channels, then it would be the same behavior in both JVMs. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
jstorni |
Posted: Thu Jul 27, 2006 6:32 am Post subject: |
|
|
Novice
Joined: 03 Feb 2006 Posts: 10
|
Well,
We still have the same problem, but, the sample servlet works ok in another WAS instance (Win2000), that has the same fixpack level applied.
Seems to be a problem of WAS, so it would be great if anyone has an idea about this. If no, i will post this problem in a WAS related forum.
I'm very concerned about this problem. It doesn't have any logic.....
Thanks all
Javier Storni |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Jul 27, 2006 2:05 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Strange question but if you are using WAS why are you using java base classes and not JMS which provides you with automatic pooling and transaction handling and such?
 _________________ MQ & Broker admin |
|
Back to top |
|
 |
jstorni |
Posted: Fri Jul 28, 2006 4:33 am Post subject: |
|
|
Novice
Joined: 03 Feb 2006 Posts: 10
|
fjb_saper wrote: |
Strange question but if you are using WAS why are you using java base classes and not JMS which provides you with automatic pooling and transaction handling and such?
 |
Because we are using non-java channels (ie: mainframe, vb apps, etc).
We have the issue of the connection creation from non-java apps and the issue of the specific JMS payload that have to be decoded to threat them as plain MQ messages.
Many thanks.
Javier Storni |
|
Back to top |
|
 |
fjb_saper |
Posted: Fri Jul 28, 2006 5:04 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Should be no problem at all. Just specify targetClient=MQ in the jndi for the queues or add "?targetClient=1" at the end of the uri:
Quote: |
"queue://MYQMGR/MYQUEUE?targetClient=1" |
and you will suppress the JMS RFH header.
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
djbosco29 |
Posted: Tue Aug 08, 2006 8:47 am Post subject: |
|
|
Newbie
Joined: 08 Aug 2006 Posts: 1
|
This is the code revisited:
Code: |
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Hashtable;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import com.ibm.mq.MQC;
import com.ibm.mq.MQException;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.MQSimpleConnectionManager;
/**
* Servlet implementation class for Servlet: ConnectionTest
*
* @web.servlet
* name="ConnectionTest"
* display-name="ConnectionTest"
*
* @web.servlet-mapping
* url-pattern="/ConnectionTest"
*
*/
public class ConnectionTest extends /*javax.servlet.http. */ HttpServlet implements /*javax.servlet.*/Servlet
{
static final long serialVersionUID=1;
int QM_PORT = 5102;
MQQueueManager[] qmgrs = new MQQueueManager[10];
MQQueue[] qRequests = new MQQueue[10];
Hashtable myProps = new Hashtable();
MQSimpleConnectionManager connMgr = new MQSimpleConnectionManager();
public ConnectionTest() {
super();
System.out.println("Starting");
}
protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException
{
arg1.setContentType("text/html");
arg1.getWriter().println("<html><head><title>Listo</title></head><body>Listo!</body></html>");
}
protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
}
public void init(ServletConfig arg0) throws ServletException {
System.out.println("Connecting");
// Sets the default connection manager
MQEnvironment.setDefaultConnectionManager(connMgr);
// A time out for "disconnected" connections.
connMgr.setTimeout(10);
myProps.put(MQC.HOST_NAME_PROPERTY, "172.28.3.27");
myProps.put(MQC.PORT_PROPERTY, new Integer(QM_PORT));
myProps.put(MQC.CHANNEL_PROPERTY, "MQTEST");
for (int n=0; n < 10; n++) {
MQQueueManager qmgr = null;
MQQueue qRequest = null;
try {
// connMgr is the connection Manager, if you dont't specify them
//
// qmgr = new MQQueueManager("TQMP2GLXP2G0302",myProps,connMgr);
qmgr = new MQQueueManager("TQMP2GLXP2G0302",myProps);
qRequest = qmgr.accessQueue("TARHSBC.FWORK.P2G.XACT_REQ",
MQC.MQOO_FAIL_IF_QUIESCING + MQC.MQOO_OUTPUT);
} catch (MQException e) {
e.printStackTrace();
}
qmgrs[n] = qmgr;
qRequests[n] = qRequest;
}
}
public void destroy() {
for (int n=0; n < 10; n++) {
try {
qRequests[n].close();
qmgrs[n].close();
qmgrs[n].disconnect();
System.out.println("Disconnected " + n);
System.out.println(qmgrs[n].isConnected());
qmgrs[n] = null;
} catch (MQException e) {
e.printStackTrace();
}
}
System.out.println("Disconnected");
}
} |
The solution is using an instance of MQSimpleConnectionManager class, to manage the connection pool.
If you don't specify one, the MQ Java API, uses a default connection manager (runs directly in the JVM), that only will shutdown when the when the JVM ends or are under memory pressure.
In this example i'm using an instance of MQSimpleConnectionManager, named connMgr, and set to default to environment using
Code: |
MQEnvironment.setDefaultConnectionManager(connMgr); |
When the servlet finalizes, this connection manager also finalizes, closing all connections thats own.
DJ. |
|
Back to top |
|
 |
|