Chris,

Yes, this is where this conversation started.  The pundits all think that I'm 
generating too many connections, and the suspicion is that this is being caused 
by a memory leak, i.e., some connections being created that are not being 
closed.  This could be correct, but so far, I have been unable to find any such 
leak.  Still looking.

Dan  

-----Original Message-----
From: Christopher Schultz <ch...@christopherschultz.net> 
Sent: Friday, August 15, 2025 1:07 PM
To: users@tomcat.apache.org
Subject: Re: [EXTERNAL EMAIL] How to access a REST service

Dan,

The only reason we are all looking for resource leaks (technically not memory 
leaks, but leaks nonetheless) is because it's the best explanation for why your 
connection pool seems to be running dry.

I don't think that switching to Tomcat (or TomEE) is going to make any 
difference.

-chris

On 8/15/25 12:33 PM, Daniel Schwartz wrote:
> 
> 
> -----Original Message-----
> From: Christopher Schultz <ch...@christopherschultz.net>
> Sent: Friday, August 15, 2025 12:18 PM
> To: users@tomcat.apache.org
> Subject: Re: [EXTERNAL EMAIL] How to access a REST service
> 
> Daniel,
> 
> On 8/15/25 12:49 AM, Daniel Schwartz wrote:
>> Robert (and all),
>>
>> I will work on answers your various questions.  However, I decided to first 
>> explore the comment (by someone) that a servlet can "swallow" an exception, 
>> which I take to mean that it can throw an exception without reporting the 
>> exception or terminating the program.
>>
>> I have this system running on a PC identified as localhost. The test URL is:
>>
>> https://urldefense.proofpoint.com/v2/url?u=http-3A__localhost-3A8080_
>> H 
>> olidaysRESTJSON-2D1.0-2DSNAPSHOT_webresources_holidaysandevents_count
>> r 
>> ies&d=DwICaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AbCalLxz
>> o 
>> pgQUG9LLcXdB80OM-GtDfItX76RMxNYqz4&m=NKm1FUayvDzFHyhbqCI0JR32OpW1rfTe
>> d 
>> HFkAoC_xT6Cjqt4-wsVFtYKPtR38vFY&s=4BYNb88ZN6WvyMyyZcR1FyT6Jg-qa4JSDa9
>> P
>> xsSFgB4&e=
>>
>> I ran two tests.  First, I wrote in code to throw an SQL exception, which 
>> did get caught in my catch clause, which printed out some messages and a 
>> stack trace.  The web browser showed the retrieved list of countries, but 
>> nothing else.
>>
>> Second, I replaced the line that throws the SQL exception by one that tries 
>> to do a division by zero.  This of course was not caught, but it did print 
>> out a stack trace and reported a 505 error in the browser, and the program 
>> did terminate.
>>
>> I take this to mean that exceptions are not being "swallowed" by my program. 
>>  When/if an exception occurs, there is definitely some indication of this, 
>> either in the server.log or the browser.  Because I have never seen either 
>> of these actions, I'm fairly sure that my program is not throwing exceptions 
>> and all database connections are being closed immediately after they are 
>> used, i.e., no memory leaks in this respect.
>>
>> The actual code fragments and outputs are copied below.
>>
>> ----------------------------------------------------------------
>> The code that throws the SQL exception
>> ----------------------------------------------------------------
>>       @GET
>>       @Path("/countries")
>>       @Produces(MediaType.APPLICATION_JSON)
>>       public String getJsonCountries() {
>>           if (TempDataStorage.countryList == null) {
>>               Connection connection = null;
>>               try {
>>                   connection = dataSource.getConnection();
>>                   System.out.println("countries connection has been opened");
>>                   TempDataStorage.countryList = 
>> GetCountryList.doIt(connection);
>>                   throw new SQLException("testing sql exception");
>> //                connection.close();
>> //                System.out.println("countries connection has been closed");
>>               } catch (SQLException e) {
>>                   System.out.println(e);
>>                   System.out.println("catching sql exception");
>>                   if (connection != null) {
>>                       try {
>>                           connection.close();
>>                       } catch (SQLException ex) {
>>                           System.out.println(ex);
>>                       }
>>                   }
>>               }
>>           }
> 
> 100% connection leak every time, guaranteed.
> 
> You are never closing the connection, because it's been commented out.
> Perhaps this was just for testing, because I see you are throwing an 
> exception.
> 
> DGS: When I put in the throw statement, I had to comment out those two lines 
> because the Java compiler complains that they are unreachable.  This was just 
> to test for what would happen if an SQL exception was thrown, in which case, 
> yes, there will be a memory.  The point is that my program never throws SQL 
> exceptions, because if it did, I would know about it.
> 
> The conn.close() *MUST* be in a finally {} block. Do not put it in the try 
> block. Do not put it in the catch block. Always put it in the finally block.
> 
> DGS: Sounds like good advice.  I'll do this and see if it makes a difference.
> 
>> ------------------------------------------------------------------
>> The output in the server.log file
>> ------------------------------------------------------------------
>> [2025-08-14T23:34:42.019-0400] [glassfish 4.1] [INFO] [] [] [tid: 
>> _ThreadID=40 _ThreadName=Thread-8] [timeMillis: 1755228882019] [levelValue: 
>> 800] [[
>>     countries connection has been opened]]
>>
>> [2025-08-14T23:34:42.022-0400] [glassfish 4.1] [INFO] [] [] [tid: 
>> _ThreadID=40 _ThreadName=Thread-8] [timeMillis: 1755228882022] [levelValue: 
>> 800] [[
>>     java.sql.SQLException: testing sql exception
>>      at
>> com.worldholidaysandevents.restjsonwebservice.HolidaysRESTJSONResourc
>> e
>> .getJsonCountries(HolidaysRESTJSONResource.java:54)
>>
>>           ... stack trace ...
>>
>> [2025-08-14T23:34:42.022-0400] [glassfish 4.1] [INFO] [] [] [tid: 
>> _ThreadID=40 _ThreadName=Thread-8] [timeMillis: 1755228882022] [levelValue: 
>> 800] [[
>>     catching sql exception]]
> 
> ... and the server does not crash. You can make any request without 
> restarting Glassfish, right?
> 
>> ----------------------------------------------------------------
>> The code that divides by zero
>> ----------------------------------------------------------------
>>       @GET
>>       @Path("/countries")
>>       @Produces(MediaType.APPLICATION_JSON)
>>       public String getJsonCountries() {
>>           if (TempDataStorage.countryList == null) {
>>               Connection connection = null;
>>               try {
>>                   connection = dataSource.getConnection();
>>                   System.out.println("countries connection has been opened");
>>                   TempDataStorage.countryList = 
>> GetCountryList.doIt(connection);
>>                   float something = 1/0;
>>                   connection.close();
>>                   System.out.println("countries connection has been closed");
>>               } catch (SQLException e) {
>>                   System.out.println(e);
>>                   System.out.println("catching sql exception");
>>                   if (connection != null) {
>>                       try {
>>                           connection.close();
>>                       } catch (SQLException ex) {
>>                           System.out.println(ex);
>>                       }
>>                   }
>>               }
>>           }
> 
> 
> 100% connection leak every time, guaranteed.
> 
> You are never closing the connection, because your code is throwing an 
> uncaught exception (divide by zero) Perhaps this was just for testing, 
> because I see you are intentionally dividing by zero.
> 
> DGS: Right.  This was to test for what would happen if a non-SQL exception 
> were thrown, i.e., one that is not caught in the catch clause.   This created 
> a 505 error and the program quit running.  Here the point is that, if 
> something like this were to happen, I would certainly know about it, and it 
> has never happened, so no memory leak is being created in this way.
> 
> The conn.close() *MUST* be in a finally {} block. Do not put it in the try 
> block. Do not put it in the catch block. Always put it in the finally block.
> 
> DGS: Thanks again.  I'll do this and see if it makes any difference in the 
> connection pooling.
> 
> -chris
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to