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=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> > > >