Re: DBCP Statement already closed .... how?

2003-11-25 Thread Antony Paul
Check this link
http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jndi-datasource-examples-how
to.html#Common%20Problems

forward the request only after the connection is closed. ie after finally
block.

Antony Paul.
- Original Message -
From: Anthony Presley [EMAIL PROTECTED]
To: Jakarta Commons Users List [EMAIL PROTECTED]
Sent: Tuesday, November 25, 2003 11:31 AM
Subject: Re: DBCP Statement already closed  how?


 On Mon, 2003-11-24 at 18:18, Vic Cekvenich wrote:
  Consider testing the app before deploying, such as OpenSTA.

 Agreed.  It was tested relatively extensively for about six months
 amongst the various offices, with no problems.  Problems occur only when
 everyone is on it.

  What DAO layer are you using?
  (ibatis, hibrenate, ?)

 Not using one, using JDBC directly through the DBCP commons.  Using one
 would require retooling the 100K+ lines of code.

 Following is some example code, again, it works fine with one request to
 the servlet (say, I click and load one client).  But, if I click on more
 than one client (say, six one after another), I start getting Error
 500's, and the logs read Connection closed or Statement already
 closed.  This appears to happen (from what I can tell) most often in
 the JSP.  My theory, currently, is:

 Servlet is called / created
 JDBC calls made / JSP called (via forward)
 Connection is closed
 Return from forward to JSP
 Finally{} from try block is called, connection is not null, but not
 open, error is thrown.

 Of course, unless the app is grabbing the SAME connection, I don't see
 why this would be happening (no JDBC calls occur in the forwards).

 On the other hand, closing the connection prior to the forward() doesn't
 give the above errors, but does give the error:

 java.lang.IllegalStateException
 at

org.apache.coyote.tomcat4.CoyoteResponseFacade.sendRedirect(CoyoteResponseFa
cade.java:340)

 What does that mean Google's not helping too much?

 Some example code:

   protected void processRequest(HttpServletRequest request,
 HttpServletResponse response)
   throws ServletException, java.io.IOException {
 // Create / validate the current session
 session = request.getSession(true);
 if (session == null) {
   setErr(SESSION_ERR);
   err();
   return;
 } else {
   username = request.getRemoteUser();
 }

 try {
   javax.servlet.ServletContext context = getServletContext();
   String dbInit = context.getInitParameter(dbInit);
   if (dbInit == null) {
 setError(DBINIT_ERR);
 err();
 return;
   }

   Context ctx = new InitialContext();
   if (ctx == null) {
 setError(CONTEXT_ERR);
 err();
 return;
   }

   DataSource ds = (DataSource) ctx.lookup(dbInit);
   if (ds != null) {
 conn = ds.getConnection();
   } else {
 setError(CONTEXT_ERR);
 err();
 return;
   }

   if (conn == null || conn.isClosed()) {
 // Try again to fetch a new connection?
 log(Connection was closed);
 while (conn == null || conn.isClosed()) {
   conn = ds.getConnection();
 }
 log(Reopened the connection);
   }

   // Did not make a valid connection for some reason, take to error
 screen
   if (conn == null) {
 setError(DBNULL_ERR);
 err();
 return;
   } else {
 // Should be a valid user
 if (username == null) {
   setError(NOUSER_ERR);
   err();
   try {
 if (conn != null) {
   conn.close();
   conn = null;
 }
   } catch (SQLException e) { ; }
   return;
 }
   }

   log(Sure of connection ... should NEVER be closed.);
 } catch (Exception e) {
   setError(CONTEXT_ERR);
   err();
   try {
 if (conn != null) {
   conn.close();
   conn = null;
 }
   } catch (SQLException ex) { ; }
   return;
 }

 // Valid user, valid roles
 // Process their data
 String action = (String) request.getParameter(action);
 String type = (String) request.getParameter(type);
 if (action == null) {
   // No action to perform, error
   setError(ACTION_ERR);
   err();
   try {
 if (conn != null) {
   conn.close();
   conn = null;
 }
   } catch (SQLException e) { ; }
 } else if (action.equalsIgnoreCase(search)) {
   // LOOKING for a client or lead
   // Search based on lname, fname AND/OR unumber

   String lname = request.getParameter(lname);
   String fname = request.getParameter(fname);
   String unum = request.getParameter(clientnr);
   try {
 DoSearch(request);
   } catch (Exception e) {
 setError(Error searching clients for:  + username);
 setExtraErr(e.getMessage());
 err();
   } finally {
 try {
   log(Closing

Re: DBCP Statement already closed .... how?

2003-11-25 Thread Ben Walding
I suspect a lot of your problems are due to code duplication.  How so?

You have the same boilerplate code for closing the connection in several 
places - extract it into a method.

Re: this code.

Context ctx = new InitialContext();
 if (ctx == null) {
   setError(CONTEXT_ERR);
   err();
   return;
 }
I haven't closely read the JLS, but I doubt this could even happen.  The constructor either succeeds or throws an exception.

while (conn == null || conn.isClosed()) {
 conn = ds.getConnection();
}
This will thrash your machine while it tries to acquire a connection if the DB is down, at least put a wait state in.



   session = request.getSession(true);
   if (session == null) {
 setErr(SESSION_ERR);
 err();
 return;
   } else {
 username = request.getRemoteUser();
   }
According to the spec, request.getSession() / request.getSession(true) will create a session if none exists.  Hence my reading suggests that session will never be null for your if test.  



Of course this doesn't really answer your question at hand - why are my connections falling apart.  I suspect that if you cleaned things up and made it more modular, you would start to see where your connections would be getting used.  I suspect that you are probably throwing away a connection in some other code - eg Client, but not realising this inside your servlet. This will typically be caused by unclear responsibilities of components. eg. Why does Client need a connection?  would they be better off with a datasource that they can acquire a connection from and destroy themselves?   

Since there is virtually no JDBC code in this example I assume that most of it occurs in LookupGeneral and DoLookup etc, the code for those is probably of more interest.

IllegalStateExceptions typically occur if you acquire the PrintWriter 
and then try to do a sendRedirect  or something along those lines, 
because your doGet method is one big if-then-else nest, it is really 
hard to work out where this might be occurring.  Better to split out the 
actions out into methods where you can properly see if they doing bad 
things one at a time.

Cheers,

Ben

Anthony Presley wrote:

On Mon, 2003-11-24 at 18:18, Vic Cekvenich wrote:
 

Consider testing the app before deploying, such as OpenSTA.
   

Agreed.  It was tested relatively extensively for about six months
amongst the various offices, with no problems.  Problems occur only when
everyone is on it.
 

What DAO layer are you using?
(ibatis, hibrenate, ?)
   

Not using one, using JDBC directly through the DBCP commons.  Using one
would require retooling the 100K+ lines of code.
Following is some example code, again, it works fine with one request to
the servlet (say, I click and load one client).  But, if I click on more
than one client (say, six one after another), I start getting Error
500's, and the logs read Connection closed or Statement already
closed.  This appears to happen (from what I can tell) most often in
the JSP.  My theory, currently, is:
Servlet is called / created
JDBC calls made / JSP called (via forward)
Connection is closed
Return from forward to JSP
Finally{} from try block is called, connection is not null, but not
open, error is thrown.
Of course, unless the app is grabbing the SAME connection, I don't see
why this would be happening (no JDBC calls occur in the forwards).
On the other hand, closing the connection prior to the forward() doesn't
give the above errors, but does give the error:
java.lang.IllegalStateException
   at
org.apache.coyote.tomcat4.CoyoteResponseFacade.sendRedirect(CoyoteResponseFacade.java:340)
What does that mean Google's not helping too much?

Some example code:

 protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
 throws ServletException, java.io.IOException {
   // Create / validate the current session
   session = request.getSession(true);
   if (session == null) {
 setErr(SESSION_ERR);
 err();
 return;
   } else {
 username = request.getRemoteUser();
   }
   
   try {
 javax.servlet.ServletContext context = getServletContext();
 String dbInit = context.getInitParameter(dbInit);
 if (dbInit == null) {
   setError(DBINIT_ERR);
   err();
   return;
 }
 
 Context ctx = new InitialContext();
 if (ctx == null) {
   setError(CONTEXT_ERR);
   err();
   return;
 }
 
 DataSource ds = (DataSource) ctx.lookup(dbInit);
 if (ds != null) {
   conn = ds.getConnection();
 } else {
   setError(CONTEXT_ERR);
   err();
   return;
 }
 
 if (conn == null || conn.isClosed()) {
   // Try again to fetch a new connection?
   log(Connection was closed);
   while (conn == null || conn.isClosed()) {
 conn = ds.getConnection();
   }
   log(Reopened the connection);
 }
 
 // Did not make a valid connection for some 

Re: DBCP Statement already closed .... how?

2003-11-25 Thread John Zoetebier
It trick is to isolate the problem:
There are 3 options available.
1) Jakarta DBCP 1.1
2) Database server
3) Problem in code
I did a test with DBCP 1.1 and McKoi.
This test can be done outside Tomcat, so it is easy to isolate the root 
cause.
I fired off rapidly a number of connections to the server.
To my big surprise the process is hanging when the number of connections 
exceeds 8.
I will look into this further tomorrow and repeat the same test without 
DBCP.
That way I can easily check if the problem is in DBCP or the database 
server.
My bet is that there is a problem in DBCP.
Let you know how it went.

--
John Zoetebier
Web site: http://www.transparent.co.nz


On Mon, 24 Nov 2003 22:55:42 -0600, Anthony Presley 
[EMAIL PROTECTED] wrote:

On Tue, 2003-11-25 at 08:15, John Zoetebier wrote:
Could this be the problem ?
 parameter
 namemaxActive/name
 value15/value
 /parameter
This tells JDBC that the maximum number of connection to be borrowed at
any point in time is 15
Increase it to 1000 and test again.
I moved it to 1000, and maxIdle to 100, and get the same errors.

--Anthony

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: DBCP Statement already closed .... how?

2003-11-25 Thread Anthony Presley
Ok ... so I took Ben's advice and decided to (at least for testing) yank
a bunch of code, and see about a slightly more modular approach.  Also,
thanks to Antony, I am forwarding AFTER the database close.  Here's what
I've found 

Closing's were extracted into a method, and the while (conn == null) was
pulled out.

I also pulled everything but the following code [below].  In it, I have
yanked the DBCP code and am establishing a single connection in the
init(), which stays open until the destroy() method is called.  Not a
great solution, but wanted to see if it was DBCP related.

As John pointed out, it is DBCP related (possibly) ... however, I can
generate the same error's (albeit, fewer of them) when using straight
JDBC Connections.  For instance:

Scenario 1 (Using DBCP):
- Call the servlet (1 time)
- Redirected to JSP file(s)
- Display of information correctly [GOOD]

- Call the servlet (5 times)
- Redirected to JSP file(s)
- Display of information correctly 1 of the 5 times [BAD]

Scenario 2 (NOT Using DBCP):
- Call the servlet (1 time)
- Redirected to JSP file(s)
- Display of information correctly [GOOD]

- Call the servlet (5 times)
- Redirected to JSP file(s)
- Display of information correctly 3 of the 5 times [BAD,BETTER]

Scenario 3 (NOT Using DBCP, Simplified JSP file):
- Call the servlet (1 time)
- Redirected to JSP file(s)
- Display of information correctly [GOOD]

- Call the servlet (5 times)
- Redirected to JSP file(s)
- Display of information correctly 4 of the 5 times [BAD,BETTER]

I'm not using a JK connector, or Apache in my testing, just plain Tomcat
on port 8080.

However, what I'm beginning to wonder and note is:
a.  Using DBCP IS causing some of the problem.
b.  By using more simple JSP files, I can decrease the chance of
errors, but 4/5 is still not good.  Is there a limit to the number of
active sessions, or amount of data I can put in the session, or
processing time (less than 1 or 2 seconds) that I'm missing?  A workload
of 5 servlets  5 JSP's (each calling about 3 other JSP's, except in
the simplified test) doesn't seem like a lot.

My modified code is below.  Please NOTE ... I can tell by the logs that
it gets done with all JDBC calls, and does the forward, whereby it's
occasionally (but not consistently) dieing in the JSP files.  In the
case of the simplified test, the JSP file pulls three session variables
and displays a true / false on the screen.  I've checked with a grep
tool, and I'm not closing or accessing the connection in any way in the
JSPs.

This is frustrating ... Thanks for everyone's help.

  protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
  throws ServletException, java.io.IOException {
set(request, response);
setServlet(InternalClients);

// Create / validate the current session
session = request.getSession(true);
username = request.getRemoteUser();

try {
  if (conn == null || conn.isClosed()) {
// Try again to fetch a new connection?
log(Connection was closed);
init();
  }
  
  // Did not make a valid connection for some reason, take to error
screen
  if (conn == null) {
setError(DBNULL_ERR);
err();
doDBClose();
return;
  } else {
// Should be a valid user
if (username == null) {
  setError(NOUSER_ERR);
  err();
  doDBClose();
  return;
}
  }
  
  log(Sure of connection ... should NEVER be closed.);
} catch (Exception e) {
  setError(CONTEXT_ERR);
  err();
  doDBClose();
  return;
}

// Valid user, valid roles
// Process their data
String action = (String) request.getParameter(action);
String type = (String) request.getParameter(type);
if (action == null) {
  // No action to perform, error
  setError(ACTION_ERR);
  err();
  doDBClose();
} else if (action.equalsIgnoreCase(search)) {
  // LOOKING for a client or lead
  // Search based on lname, fname AND/OR unumber
  
  String lname = request.getParameter(lname);
  String fname = request.getParameter(fname);
  String unum = request.getParameter(clientnr);
  try {
DoSearch(request);
  } catch (Exception e) {
setError(Error searching clients for:  + username);
setExtraErr(e.getMessage());
err();
  } finally {
doDBClose();
  }
} else if (action.equalsIgnoreCase(view)) {
  try {
Client c = new Client(conn, true);

String cname = request.getParameter(clientnr);
log(Looking up username:  + username);

if (!c.queryExactUserName(cname)) {
  // Should be an error, but instead, set as a message...
  

Re: DBCP Statement already closed .... how?

2003-11-25 Thread Dirk Verbeeck
The problem with the example code you posted is then conn variable.
It should be declared inside the method (local variable) and not as a member 
variable.

Your example works if only one request is processed.
A second request overwrites the connection of the first one.
So the first connection is lost and at the end, both requests will try to 
close the same connection two times triggering the exception you see.

-- Dirk



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: DBCP Statement already closed .... how?

2003-11-25 Thread John Zoetebier
Results of DBCP 1.1 testing.

My first tests showed that:
- There is no problem with McKoi  handling large number of connections.
Meximum number of connections in my test is 50
- DBCP hung on 9th connection
After some further digging I discovered that I had not set MaxIdle in my 
tests.
After setting: genericConnectionPool.setmaxIdle(-1) there was not problem 
with DBCP anymore.
You have to be aware though of an internal preset number of 8 connections, 
in stead of unlimited which I would expect to be the default. 8 
connections seems rather arbitrary to my opinion.

My tests show without any doubt that you can exclude DBCP 1.1 as a 
possible source for your problem.

--
John Zoetebier
Web site: http://www.transparent.co.nz
-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: DBCP Statement already closed .... how?

2003-11-25 Thread Anthony Presley
Thank you Dirk . where do you live?  I owe you a Pizza.

This did, in fact, solve almost all of my problems.  Subtle [to me].

However, I have a remaining issue, and I've narrowed it down to the
following lines of code.  I'll post in the tomcat user group, but
thought someone here might have a pearl of wisdom.

Nine times out of ten, multiple requests work perfectly.  However, in
the one time out of ten that it doesn't, my code is throwing an
Exception with this:

  try {
if (rd != null)
  rd.forward(req, res);
else {
  log(RD is NULL, MAJOR ERROR);
}
  } catch (ServletException e) {
log(5ERROR ServletException:  + e.getMessage());
e.printStackTrace();
  } catch (java.io.IOException e) {
log(5ERROR java.io.IOException:  + e.getMessage());
e.printStackTrace();
  } catch (Exception e) {
log(5ERROR Exception:  + e.getMessage());
e.printStackTrace();
  }

Doing a reload on it, it works fine.  IE, what is being sent (the URL)
does start with a /, and rd is NOT null (neither are req or res).

The Error is: 
5ERROR Exception: Cannot forward after response has been commit

Googling is again, less than helpful (although it appeared that in
Version 3.3 this error was common, I'm now on 4.1).

On Tue, 2003-11-25 at 15:15, Dirk Verbeeck wrote:
 The problem with the example code you posted is then conn variable.
 It should be declared inside the method (local variable) and not as a member 
 variable.
 
 Your example works if only one request is processed.
 A second request overwrites the connection of the first one.
 So the first connection is lost and at the end, both requests will try to 
 close the same connection two times triggering the exception you see.
 
 -- Dirk


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: DBCP Statement already closed .... how?

2003-11-25 Thread John Zoetebier
There is a method you can check if your code leaves connections open.
From web site 
http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jndi-datasource-examples-howto.html#Common%20Problems

==
There is a solution to this problem. The Jakarta-Commons DBCP can be 
configured to track and recover these abandoned dB connections. Not only 
can it recover them, but also generate a stack trace for the code which 
opened these resources and never closed them.

To configure a DBCP DataSource so that abandoned dB connections are 
removed and recycled add the following paramater to the ResourceParams 
configuration for your DBCP DataSource Resource:
			
	

parameter
  nameremoveAbandoned/name
  valuetrue/value
/parameter
	
			
When available db connections run low DBCP will recover and recyle any 
abandoned dB connections it finds. The default is false.

Use the removeAbandonedTimeout parameter to set the number of seconds a dB 
connection has been idle before it is considered abandoned.
			
	

parameter
  nameremoveAbandonedTimeout/name
  value60/value
/parameter


The default timeout for removing abandoned connections is 300 seconds.
The logAbandoned parameter can be set to true if you want DBCP to log a 
stack trace of the code which abandoned the dB connection resources.
			
	

parameter
  namelogAbandoned/name
  valuetrue/value
/parameter


The default is false.
==
--
John Zoetebier
Web site: http://www.transparent.co.nz
-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: DBCP Statement already closed .... how?

2003-11-25 Thread Craig R. McClanahan
Quoting Anthony Presley [EMAIL PROTECTED]:

 Thank you Dirk . where do you live?  I owe you a Pizza.
 
 This did, in fact, solve almost all of my problems.  Subtle [to me].
 
 However, I have a remaining issue, and I've narrowed it down to the
 following lines of code.  I'll post in the tomcat user group, but
 thought someone here might have a pearl of wisdom.
 
 Nine times out of ten, multiple requests work perfectly.  However, in
 the one time out of ten that it doesn't, my code is throwing an
 Exception with this:
 
   try {
 if (rd != null)
   rd.forward(req, res);
 else {
   log(RD is NULL, MAJOR ERROR);
 }
   } catch (ServletException e) {
 log(5ERROR ServletException:  + e.getMessage());
 e.printStackTrace();
   } catch (java.io.IOException e) {
 log(5ERROR java.io.IOException:  + e.getMessage());
 e.printStackTrace();
   } catch (Exception e) {
 log(5ERROR Exception:  + e.getMessage());
 e.printStackTrace();
   }
 
 Doing a reload on it, it works fine.  IE, what is being sent (the URL)
 does start with a /, and rd is NOT null (neither are req or res).
 
 The Error is: 
   5ERROR Exception: Cannot forward after response has been commit
 

It means you tried to call RequestDispatcher.forward() after the current
response has been committed :-).

To understand what's really happening, you need to be a little bit familiar with
how servlets work.  When you start writing to a response page, the output you
write is buffered, up to the point where the buffer size has been exceeded. 
Prior to that point, you can call forward() -- which, among other things,
erases any buffered output so that the new resource or page can write the entre
content of the response.

However, if you've already written more characters than the size of the output
buffer, the HTTP headers (and the first part of the response) are actually sent
to the client.  After that point, the response is considered to be committed
and you can no longer do a RequestDispatcher.forward() call.

So, how big is the page buffer?  Ah, there's the rub ... it's not specified, so
it varies by container.  However, you can control it by calling
response.setBufferSize() if you are writing directly from a servlet, or using
the buffer attribute on the %@ page % directive if you're using JSP.  You
need to ensure that you haven't already written more characters than the buffer
size before you execute the forward() call.

Note that this kind of problem would never occur if you were using an MVC-based
framework like Struts http://jakarta.apache.org/struts, because the business
logic that processed the incoming form submit would never output anything to
the response -- it would merely perform the required processing, then forward()
to a servlet or JSP page to create the actual output.

Craig McClanahan


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: DBCP Statement already closed .... how?

2003-11-24 Thread Vic Cekvenich
Consider testing the app before deploying, such as OpenSTA.

What DAO layer are you using?
(ibatis, hibrenate, ?)
.V

Anthony Presley wrote:
Hello all 

I've been using DBCP to develop an application for the last 12 months,
and it's finally been placed into active use.  Which is great ...
except that it didn't scale very well.  When being used by less than 10
or 15 users, it's fine.  However, as soon as the number of users
increases (or I simulate by clicking on a bunch of database links at one
time), I start getting a lot of 'Statement' already closed. error's in
my logs.
As far as I can tell, I'm not doing any double closings.  Again, this
works fine and dandy when there's only a few users, but once several
people get on it, it starts with these errors, and they're rather
annoying.  Most intruiging is that if you wait a few seconds, then try
again, requests to the database work fine.
I've thrown in a LOT of log() statements in my code to ensure that the
database connections are, in fact, being closed and returned to the pool
-- and they are.  From what I can tell, they're being closed somewhere
in the middle of the processing of them.
My Tomcat config looks like (and I'm using DBCP 1.1 and nightly (have
tried both) and Pool 1.1) :
ResourceParams name=jdbc/ifx scope=Shareable
parameter
namefactory/name
   
valueorg.apache.commons.dbcp.BasicDataSourceFactory/value
/parameter

parameter
namemaxActive/name
value15/value
/parameter
parameter
namemaxIdle/name
value3/value
/parameter
parameter
namevalidationQuery/name
valueSELECT user.id FROM user WHERE id =
1/value
/parameter
parameter
nameremoveAbandonedTimeout/name
value300/value
/parameter

parameter
nameremoveAbandoned/name
valuetrue/value
/parameter

parameter
namemaxWait/name
value1/value
/parameter
parameter
namedriverClassName/name
valuecom.informix.jdbc.IfxDriver/value
/parameter
parameter
 nameurl/name

valuejdbc:informix-sqli://ids:1314/development:INFORMIXSERVER=london_net/value
/parameter
/ResourceParams
A chunk of the log is:

2003-11-24 17:04:29 InternalClients: Closing connections
2003-11-24 17:04:29 InternalClients: ERROR: Servlet InternalClients, SQL
Error lookup up General Information: 'Statement' already closed.
RootCause: null: /Error
2003-11-24 17:04:29 InternalClients: ERROR: Servlet InternalClients,
General Error viewing internal client information: null RootCause: null:
/Error
2003-11-24 17:04:29 InternalClients: Closing connections
2003-11-24 17:04:29 InternalClients: Closed
2003-11-24 17:04:29 StandardWrapperValve[InternalClients]:
Servlet.service() for servlet InternalClients threw exception
java.lang.IllegalStateException
at
org.apache.coyote.tomcat4.CoyoteResponseFacade.sendRedirect(CoyoteResponseFacade.java:340)
at azure.servlets.Azure.err(Azure.java:76)
at
azure.servlets.InternalClients.processRequest(InternalClients.java:199)
at azure.servlets.InternalClients.doGet(InternalClients.java:34)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
Again, the link that generated the error  clicking on it right after
it logged these error's, it works fine.  Which obviously (to me?) leads
me right to ... a problem with the DBCP, or the DB, or my code.  These
are not simple problems to troubleshoot, it appears.
I can post the code the generates this  if that would help.  At this
point in the game, I'm pretty much at my wits ends.
Any help is much appreciated 

--Anthony


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: DBCP Statement already closed .... how?

2003-11-24 Thread John Zoetebier
Could this be the problem ?
parameter
namemaxActive/name
value15/value
/parameter
This tells JDBC that the maximum number of connection to be borrowed at 
any point in time is 15
Increase it to 1000 and test again.

--
John Zoetebier
Web site: http://www.transparent.co.nz
On Mon, 24 Nov 2003 17:15:12 -0600, Anthony Presley 
[EMAIL PROTECTED] wrote:

Hello all 

I've been using DBCP to develop an application for the last 12 months,
and it's finally been placed into active use.  Which is great ...
except that it didn't scale very well.  When being used by less than 10
or 15 users, it's fine.  However, as soon as the number of users
increases (or I simulate by clicking on a bunch of database links at one
time), I start getting a lot of 'Statement' already closed. error's in
my logs.
As far as I can tell, I'm not doing any double closings.  Again, this
works fine and dandy when there's only a few users, but once several
people get on it, it starts with these errors, and they're rather
annoying.  Most intruiging is that if you wait a few seconds, then try
again, requests to the database work fine.
I've thrown in a LOT of log() statements in my code to ensure that the
database connections are, in fact, being closed and returned to the pool
-- and they are.  From what I can tell, they're being closed somewhere
in the middle of the processing of them.
My Tomcat config looks like (and I'm using DBCP 1.1 and nightly (have
tried both) and Pool 1.1) :
ResourceParams name=jdbc/ifx scope=Shareable
parameter
namefactory/name
valueorg.apache.commons.dbcp.BasicDataSourceFactory/value
/parameter
parameter
namemaxActive/name
value15/value
/parameter
parameter
namemaxIdle/name
value3/value
/parameter
parameter
namevalidationQuery/name
valueSELECT user.id FROM user WHERE id =
1/value
/parameter
parameter
nameremoveAbandonedTimeout/name
value300/value
/parameter
parameter
nameremoveAbandoned/name
valuetrue/value
/parameter
parameter
namemaxWait/name
value1/value
/parameter
parameter
namedriverClassName/name
valuecom.informix.jdbc.IfxDriver/value
/parameter
parameter
 nameurl/name

valuejdbc:informix-sqli://ids:1314/development:INFORMIXSERVER=london_net/value
/parameter
/ResourceParams
A chunk of the log is:

2003-11-24 17:04:29 InternalClients: Closing connections
2003-11-24 17:04:29 InternalClients: ERROR: Servlet InternalClients, SQL
Error lookup up General Information: 'Statement' already closed.
RootCause: null: /Error
2003-11-24 17:04:29 InternalClients: ERROR: Servlet InternalClients,
General Error viewing internal client information: null RootCause: null:
/Error
2003-11-24 17:04:29 InternalClients: Closing connections
2003-11-24 17:04:29 InternalClients: Closed
2003-11-24 17:04:29 StandardWrapperValve[InternalClients]:
Servlet.service() for servlet InternalClients threw exception
java.lang.IllegalStateException
at
org.apache.coyote.tomcat4.CoyoteResponseFacade.sendRedirect(CoyoteResponseFacade.java:340)
at azure.servlets.Azure.err(Azure.java:76)
at
azure.servlets.InternalClients.processRequest(InternalClients.java:199)
at azure.servlets.InternalClients.doGet(InternalClients.java:34)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
Again, the link that generated the error  clicking on it right after
it logged these error's, it works fine.  Which obviously (to me?) leads
me right to ... a problem with the DBCP, or the DB, or my code.  These
are not simple problems to troubleshoot, it appears.
I can post the code the generates this  if that would help.  At this
point in the game, I'm pretty much at my wits ends.
Any help is much appreciated 

--Anthony

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: DBCP Statement already closed .... how?

2003-11-24 Thread Anthony Presley
On Mon, 2003-11-24 at 18:18, Vic Cekvenich wrote:
 Consider testing the app before deploying, such as OpenSTA.

Agreed.  It was tested relatively extensively for about six months
amongst the various offices, with no problems.  Problems occur only when
everyone is on it.

 What DAO layer are you using?
 (ibatis, hibrenate, ?)

Not using one, using JDBC directly through the DBCP commons.  Using one
would require retooling the 100K+ lines of code.

Following is some example code, again, it works fine with one request to
the servlet (say, I click and load one client).  But, if I click on more
than one client (say, six one after another), I start getting Error
500's, and the logs read Connection closed or Statement already
closed.  This appears to happen (from what I can tell) most often in
the JSP.  My theory, currently, is:

Servlet is called / created
JDBC calls made / JSP called (via forward)
Connection is closed
Return from forward to JSP
Finally{} from try block is called, connection is not null, but not
open, error is thrown.

Of course, unless the app is grabbing the SAME connection, I don't see
why this would be happening (no JDBC calls occur in the forwards).

On the other hand, closing the connection prior to the forward() doesn't
give the above errors, but does give the error:

java.lang.IllegalStateException
at
org.apache.coyote.tomcat4.CoyoteResponseFacade.sendRedirect(CoyoteResponseFacade.java:340)

What does that mean Google's not helping too much?

Some example code:

  protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
  throws ServletException, java.io.IOException {
// Create / validate the current session
session = request.getSession(true);
if (session == null) {
  setErr(SESSION_ERR);
  err();
  return;
} else {
  username = request.getRemoteUser();
}

try {
  javax.servlet.ServletContext context = getServletContext();
  String dbInit = context.getInitParameter(dbInit);
  if (dbInit == null) {
setError(DBINIT_ERR);
err();
return;
  }
  
  Context ctx = new InitialContext();
  if (ctx == null) {
setError(CONTEXT_ERR);
err();
return;
  }
  
  DataSource ds = (DataSource) ctx.lookup(dbInit);
  if (ds != null) {
conn = ds.getConnection();
  } else {
setError(CONTEXT_ERR);
err();
return;
  }
  
  if (conn == null || conn.isClosed()) {
// Try again to fetch a new connection?
log(Connection was closed);
while (conn == null || conn.isClosed()) {
  conn = ds.getConnection();
}
log(Reopened the connection);
  }
  
  // Did not make a valid connection for some reason, take to error
screen
  if (conn == null) {
setError(DBNULL_ERR);
err();
return;
  } else {
// Should be a valid user
if (username == null) {
  setError(NOUSER_ERR);
  err();
  try {
if (conn != null) {
  conn.close();
  conn = null;
}
  } catch (SQLException e) { ; }
  return;
}
  }
  
  log(Sure of connection ... should NEVER be closed.);
} catch (Exception e) {
  setError(CONTEXT_ERR);
  err();
  try {
if (conn != null) {
  conn.close();
  conn = null;
}
  } catch (SQLException ex) { ; }
  return;
}

// Valid user, valid roles
// Process their data
String action = (String) request.getParameter(action);
String type = (String) request.getParameter(type);
if (action == null) {
  // No action to perform, error
  setError(ACTION_ERR);
  err();
  try {
if (conn != null) {
  conn.close();
  conn = null;
}
  } catch (SQLException e) { ; }
} else if (action.equalsIgnoreCase(search)) {
  // LOOKING for a client or lead
  // Search based on lname, fname AND/OR unumber
  
  String lname = request.getParameter(lname);
  String fname = request.getParameter(fname);
  String unum = request.getParameter(clientnr);
  try {
DoSearch(request);
  } catch (Exception e) {
setError(Error searching clients for:  + username);
setExtraErr(e.getMessage());
err();
  } finally {
try {
  log(Closing);
  if (conn != null) {
conn.close();
conn = null;
  }
  log(Closed);
} catch (SQLException e) { ; }
  }
} else if (action.equalsIgnoreCase(view)) {
  try {
Client c = new Client(conn, true);

String cname = request.getParameter(clientnr);
log(Looking up username:  + username);

if (!c.queryExactUserName(cname)) {
  // Should be an error, but instead,