Hi Robert, You might be using a different version of Glassfish. I have 4.1 (which I realize is old). It won't let you set the minimum pool size to less than 8. If you try to do this, it reports an error and won't let you proceed. The simple test I ran shows that it is creating 8 physical connections for each logical connection. This is clearly stated by the monitoring report, and you can’t disagree with that. I have considered upgrading to a newer version of Glassfish, but this would be another project that I'm not prepared to undertake right now. The simple fact is that what I have now seem to be working, so I don't see any point in making major changes.
Dan -----Original Message----- From: Robert Turner <rtur...@e-djuster.ca.INVALID> Sent: Saturday, August 16, 2025 12:35 AM To: Tomcat Users List <users@tomcat.apache.org> Subject: Re: [EXTERNAL EMAIL] How to access a REST service Dan, FWIW, I just set up test Glassfish server, and made a trivial app to acquire and release a connection from the pool. I configured the connection with a minimum and starting size of 1. I tested with 1 connection, and it did exactly what I expected. Acquired and released 1 connection. No more connections were allocated. The setting for the minimum size is also the initial size (no surprise), and I could set that value to 1. My code to acquire the connection was this trivial code: final InitialContext ic = new InitialContext(); final DataSource ds = (DataSource) ic.lookup("test1"); try (Connection conn = ds.getConnection()) { } catch (SQLException e) { throw new Runtime exception(e); } So, I don't agree with your "conclusion" about 8 connections per. Robert On Sat, Aug 16, 2025, 00:02 Daniel Schwartz <d...@danielgschwartz.com> wrote: > 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=53616c7 > 465645f5f4a8adbed4b5cf7a587f5f4df537a8eaec1a2b42d4d58936018b1ed681a23d > 9919bf8332d2b6b61429feb03a72599510c1c3ab28d5aaddc506ec4d56aaa261fcb98b > d9aad462cad1cc8e2c0a7c87426fd5ac7bd5b6e2701e483c6c0dabfa7863325d5e1cce > 43460a01fdb3123cef7a62998f33320b7ee6a504f58e005390e8ee17f0cc8754779156 > e61decfa830f679ecb7c1779d40b153b44dd3c8946f5c5040afad656b12d548292c93d > 680a4c9c588dd499f91f4d3fe02cd457cde8bab1d939f1dcbfe104966e4bccd617fa2c > f6cf872584c675598f814ea3508244febcc34102818eff6415cdd > > > Learn More< > https://godaddy1.cloud-protect.net/email-details/?k=k1&payload=53616c7 > 465645f5f4a8adbed4b5cf7a587f5f4df537a8eaec1a2b42d4d58936018b1ed681a23d > 9919bf8332d2b6b61429feb03a72599510c1c3ab28d5aaddc506ec4d56aaa261fcb98b > d9aad462cad1cc8e2c0a7c87426fd5ac7bd5b6e2701e483c6c0dabfa7863325d5e1cce > 43460a01fdb3123cef7a62998f33320b7ee6a504f58e005390e8ee17f0cc8754779156 > e61decfa830f679ecb7c1779d40b153b44dd3c8946f5c5040afad656b12d548292c93d > 680a4c9c588dd499f91f4d3fe02cd457cde8bab1d939f1dcbfe104966e4bccd617fa2c > f6cf872584c675598f814ea3508244febcc34102818eff6415cdd > > > 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-3A80 > >>> 80_ > > >>> H > > >>> olidaysRESTJSON-2D1.0-2DSNAPSHOT_webresources_holidaysandevents_co > >>> unt > > >>> r > > >>> ies&d=DwICaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AbCal > >>> Lxz > > >>> o > > >>> pgQUG9LLcXdB80OM-GtDfItX76RMxNYqz4&m=NKm1FUayvDzFHyhbqCI0JR32OpW1r > >>> fTe > > >>> d > > >>> HFkAoC_xT6Cjqt4-wsVFtYKPtR38vFY&s=4BYNb88ZN6WvyMyyZcR1FyT6Jg-qa4JS > >>> Da9 > > >>> 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.HolidaysRESTJSONReso > >>> urc > > >>> 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> > > >