Chuck,

Okay, here is the text of the attachment.

Instance Name:
server




Resource :    HolidaysConnectionPool        Application :     
HolidaysRESTJSON-1.0-SNAPSHOT

Monitor (14 Statistics)
 JDBC Connection Pool Statistics : HolidaysConnectionPool
Name
Value
Start Time
Last Sample Time
Details
Description
NumConnCreated
8 count
Aug 15, 2025 1:26:20 AM
Aug 15, 2025 1:26:21 AM
--
The number of physical connections that were created since the last reset.
NumConnFree
8count
Aug 15, 2025 1:26:20 AM
Aug 15, 2025 1:26:21 AM
High Water Mark: 8 count
Low Water Mark: 0 count
The total number of free connections in the pool as of the last sampling.
NumConnReleased
1 count
Aug 15, 2025 1:26:20 AM
Aug 15, 2025 1:26:21 AM
--
Number of logical connections released to the pool.
NumPotentialConnLeak
0 count
Aug 15, 2025 1:26:20 AM
--
--
Number of potential connection leaks
NumConnFailedValidation
0 count
Aug 15, 2025 1:26:20 AM
--
--
The total number of connections in the connection pool that failed validation 
from the start time until the last sample time.
ConnRequestWaitTime
485millisecond
Aug 15, 2025 1:26:20 AM
Aug 15, 2025 1:26:21 AM
High Water Mark: 485 millisecond
Low Water Mark: 0 millisecond
The longest and shortest wait times of connection requests. The current value 
indicates the wait time of the last request that was serviced by the pool.
NumConnAcquired
1 count
Aug 15, 2025 1:26:20 AM
Aug 15, 2025 1:26:21 AM
--
Number of logical connections acquired from the pool.
AverageConnWaitTime
485 millisecond
Aug 15, 2025 1:26:20 AM
Aug 15, 2025 1:26:33 AM
--
Average wait-time-duration per successful connection request
NumConnDestroyed
0 count
Aug 15, 2025 1:26:20 AM
--
--
Number of physical connections that were destroyed since the last reset.
NumConnSuccessfullyMatched
0 count
Aug 15, 2025 1:26:20 AM
--
--
Number of connections succesfully matched
NumConnNotSuccessfullyMatched
0 count
Aug 15, 2025 1:26:20 AM
--
--
Number of connections rejected during matching
NumConnUsed
0count
Aug 15, 2025 1:26:20 AM
Aug 15, 2025 1:26:21 AM
High Water Mark: 1 count
Low Water Mark: 0 count
Provides connection usage statistics. The total number of connections that are 
currently being used, as well as information about the maximum number of 
connections that were used (the high water mark).
WaitQueueLength
0 count
Aug 15, 2025 1:26:20 AM
--
--
Number of connection requests in the queue waiting to be serviced.
NumConnTimedOut
0 count
Aug 15, 2025 1:26:20 AM
--
--
The total number of connections in the pool that timed out between the start 
time and the last sample time.

Regarding your statement "What is more likely is that the GlassFish connection 
pool simply initializes the configured minimum number of connections on the 
first attempt to acquire a connection.", I have no idea hat this means.

Dan

From: Chuck Caldarale <n82...@gmail.com>
Sent: Friday, August 15, 2025 11:39 PM
To: Tomcat Users List <users@tomcat.apache.org>
Subject: Re: [EXTERNAL EMAIL] How to access a REST service

> On 2025 Aug 15, at 22:03, Daniel Schwartz 
> <d...@danielgschwartz.com<mailto:d...@danielgschwartz.com>> wrote: > > I 
> think I found the answer. > > A few days ago, someone suggested that I try 
> setting the Glassfish maximum pool size to 1 and see what happens.
NkdkJdXPPEBannerStart
Be Careful With This Message
>From (Chuck Caldarale 
><n82...@gmail.com>)<https://godaddy1.cloud-protect.net/email-details/?k=k1&payload=53616c7465645f5f4a8adbed4b5cf7a587f5f4df537a8eaec1a2b42d4d58936018b1ed681a23d9919bf8332d2b6b61429feb03a72599510c1c3ab28d5aaddc506ec4d56aaa261fcb98bd9aad462cad1cc8e2c0a7c87426fd5ac7bd5b6e2701e483c6c0dabfa7863325d5e1cce43460a01fdb3123cef7a62998f33320b7ee6a504f58e005390e8ee17f0cc8754779156e61decfa830f679ecb7c1779d40b153b44dd3c8946f5c5040afad656b12d548292c93d680a4c9c588dd499f91f4d3fe02cd457cde8bab1d939f1dcbfe104966e4bccd617fa2cf6cf872584c675598f814ea3508244febcc34102818eff6415cdd>
Learn 
More<https://godaddy1.cloud-protect.net/email-details/?k=k1&payload=53616c7465645f5f4a8adbed4b5cf7a587f5f4df537a8eaec1a2b42d4d58936018b1ed681a23d9919bf8332d2b6b61429feb03a72599510c1c3ab28d5aaddc506ec4d56aaa261fcb98bd9aad462cad1cc8e2c0a7c87426fd5ac7bd5b6e2701e483c6c0dabfa7863325d5e1cce43460a01fdb3123cef7a62998f33320b7ee6a504f58e005390e8ee17f0cc8754779156e61decfa830f679ecb7c1779d40b153b44dd3c8946f5c5040afad656b12d548292c93d680a4c9c588dd499f91f4d3fe02cd457cde8bab1d939f1dcbfe104966e4bccd617fa2cf6cf872584c675598f814ea3508244febcc34102818eff6415cdd>
Potential Impersonation
The sender's identity could not be verified and someone may be impersonating 
the sender. Take caution when interacting with this message.

NkdkJdXPPEBannerEnd



> On 2025 Aug 15, at 22:03, Daniel Schwartz 
> <d...@danielgschwartz.com<mailto:d...@danielgschwartz.com>> wrote:

>

> I think I found the answer.

>

> A few days ago, someone suggested that I try setting the Glassfish maximum 
> pool size to 1 and see what happens.  I reported back that in Glassfish the 
> minimum pool size is 8, to which someone responded that this seems strange.  
> I really didn't know.  But now I do.

>

> Today I decided to run a test where I cleared out Glassfish so I could start 
> from scratch.  I executed one REST request using the URL I posted recently, 
> which returns a list of countries.  Then I looked at the Glassfish JDBC pool 
> monitor.  A PDF of this is attached.





The list strips nearly all attachments, for safely reasons. You need to post 
the text.





>  You will see that it says the following:

>

> 1. NumConnAcquired, 1 count, Number of logical connection

>

> 2. NumConnReleased, 1 count, Number of logical connections released to the 
> pool.

>

> 3. NumConnCreated, 8 count, The number of physical connections that were 
> created since the last reset.

>

> 4. NumConnFree, 8count, The total number of free connections in the pool as 
> of the last sampling.

>

> I believe that this is why the minimum pool size is 8; each logical 
> connection requires 8 physical connections.

>

> This leads me to believe that this is why the number of connections in my 
> connection pool is much larger than what one would expect.  Assuming that 
> Tomcat only requires one connection object per query, this implies that 
> Glassfish requires 8 times that amount.





I think that is extremely unlikely. What is more likely is that the GlassFish 
connection pool simply initializes the configured minimum number of connections 
on the first attempt to acquire a connection.



You can test this by making concurrent requests and seeing what happens to the 
pool counters. Try inserting a delay in your code between opening a connection 
and closing it; something like Thread.currentThread().sleep(10000) would likely 
suffice. Then initiate independent requests from several browser tabs in 
parallel; the 10-second delay should allow time for each request to grab its 
own connection from the pool while the other requests are still active.





> So, while a normal pool size for Tomcat might be 20 connections, in Glassfish 
> this same activity would require 160 connections.

>

> In any case, I'm now 100% sure that my program doesn't, and never did, have a 
> memory leak.  I have modified my code according to Chris's recommendations, 
> as this surely is good advice, but it hasn't changed the performance, since 
> no exceptions were ever being thrown.





Did you apply the try-catch-finally pattern to all DB-related objects, such as 
statements, prepared statements, and result sets?



  - Chuck





> It appears to me that Glassfish is performing normally according to its 
> internal design, and there really is no problem as long as I keep the maximum 
> pool size large enough.

>

> What do you think?

>

> Dan

>

> -----Original Message-----

> From: Christopher Schultz 
> <ch...@christopherschultz.net<mailto:ch...@christopherschultz.net>>

> Sent: Friday, August 15, 2025 1:07 PM

> To: users@tomcat.apache.org<mailto: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<mailto:ch...@christopherschultz.net>>

>> Sent: Friday, August 15, 2025 12:18 PM

>> To: users@tomcat.apache.org<mailto: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<mailto:users-unsubscr...@tomcat.apache.org>

>> For additional commands, e-mail: 
>> users-h...@tomcat.apache.org<mailto:users-h...@tomcat.apache.org>

>>

>>

>> ---------------------------------------------------------------------

>> To unsubscribe, e-mail: 
>> users-unsubscr...@tomcat.apache.org<mailto:users-unsubscr...@tomcat.apache.org>

>> For additional commands, e-mail: 
>> users-h...@tomcat.apache.org<mailto:users-h...@tomcat.apache.org>

>>

>

>

> ---------------------------------------------------------------------

> To unsubscribe, e-mail: 
> users-unsubscr...@tomcat.apache.org<mailto:users-unsubscr...@tomcat.apache.org>

> For additional commands, e-mail: 
> users-h...@tomcat.apache.org<mailto:users-h...@tomcat.apache.org>

>

>

> ---------------------------------------------------------------------

> To unsubscribe, e-mail: 
> users-unsubscr...@tomcat.apache.org<mailto:users-unsubscr...@tomcat.apache.org>

> For additional commands, e-mail: 
> users-h...@tomcat.apache.org<mailto:users-h...@tomcat.apache.org>





---------------------------------------------------------------------

To unsubscribe, e-mail: 
users-unsubscr...@tomcat.apache.org<mailto:users-unsubscr...@tomcat.apache.org>

For additional commands, e-mail: 
users-h...@tomcat.apache.org<mailto:users-h...@tomcat.apache.org>


Reply via email to