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>