Win a copy of Zero to AI - A non-technical, hype-free guide to prospering in the AI era this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Paul Clapham
  • Bear Bibeault
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • salvin francis
  • Scott Selikoff
  • fred rosenberger

NullPointerException error

 
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello. If anybody has a minute, I see this error when I start a Tomcat service....




I don't see any reference to individual classes in the error trace (as it seems to be referencing DefaultInstanceManager)...but here is the destroy() method from QueryEngineServlet...

it performs a null check on QueryEngine before it calls destroy() so I do't think it's as much a code thing as maybe a Tomcat config issue? Again, the error trace doesn't refer to a custom java class (and error line), just DefaultinstanceManager. Thank you very much for reading.





 
Marshal
Posts: 25946
69
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I dunno, it seems unlikely that Tomcat would be unloading and destroying a servlet while it's being started. So to me, there's something fishy going on. Maybe configuration, like you suggested, but I have no idea where to start looking.

Okay, that's probably not helpful. But does this error cause the startup to abort, or does it carry on to a point where you can send requests to the website?
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thank you so much....that is what is weird.  Everything seems ok otherwise in terms of requests and responses. I found the error reviewing the logs and checking for warnings and so forth. I'm worried that the chickens will come home to roost at some point with this.

There's two separate web apps with the same servlet name (the source code is very close to the same...the destroy() methods are the same) and this error doesn't specify which web app. As a result, I would think it would show up twice or not at all...but its only once...which kinda points to a Tomcat internal destroy() thing... (at org.apache.catalina.core.DefaultInstanceManager.destroyInstance)

It might possibly be when I shut the Tomcat service off...but I think it's when  starting the service. I will have to shut down the service and leave it off for a while and compare the log time.
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:I dunno, it seems unlikely that Tomcat would be unloading and destroying a servlet while it's being started. So to me, there's something fishy going on. Maybe configuration, like you suggested, but I have no idea where to start looking.

Okay, that's probably not helpful. But does this error cause the startup to abort, or does it carry on to a point where you can send requests to the website?



Hey, thank you so much for reading...just some further info...it's isolated to when I shut the Tomcat windows service down, so I'm thinking not to sweat it. I'd like for it to go away but it seems it's something with the DefaultInstanceManager.destroyInstance in Tomcat. I checked the web.xml for the two servlets and they seem ok. Maybe it's because they have the same name? It's worrisome as it seems the servlets are not being "registered" but the requests/responses all seem ok.
 
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rather that seeing the source code for Tomcat, I'd prefer seeing the full stack trace. The source code is something I can get myself, but the context I could only assume, and since Tomcat doesn't normally do that, I'd unquestionably assume wrong.

The exact same webapp code can be deployed multiple times in Tomcat. You might do so, for example, if you had 5 clients, each running the same app, but using 5 separate databases. What identifies which app instance is which is the webapp's context path, which is the URL fragment that it's deployed under, and hence answers to. For example, "https://coderanch.com/forums" might indicate that we have the CodeRanch app deployed under context path "/forums".

If you deploy a webapp by simply dropping it into TOMCAT_HOME/webapps/, the context path will be the same as the name of the WAR file or directory that you deployed. You can also deploy a webapp by creating a Context file under TOMCAT_HOME/conf/Catalina/localhost, in which case the context path will the the Context XML file's name (NOT the path you might have defined in the Context element!). So if you know a failing URL, you can always backtrack it to the deployed WAR.
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi, thank you...yeah, the two WARs are dumped into TOMCAT_HOME/webapps, but within each web.xml...the <servlet> node and subnodes are identical.

For example, <servlet-name>QueryEngineServlet</servlet-name>...etc...

the exception when the windows service is stopped refers to the servlet name... so Tomcat does have a reference to one of these servlets since it references the name, but it's seeing a null something...


org.apache.catalina.core.StandardWrapper.unload InstanceManager.destroy() for servlet [QueryEngineServlet] threw exception
java.lang.NullPointerException at org.apache.catalina.core.DefaultInstanceManager.destroyInstance (DefaultInstanceManager.java:197) at...etc...etc...


Is there a way to grab a full stack trace? It's not only what's printed in the stderr log, right?
 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Each deployed webapp is given a unique classpath. So even if a WAR is deployed under 2 different contexts, the static class values will not be shared between the webapps, nor will any objects constructed within the webapps be visible to the other webapps.

What I want as far as a Stack Trace goes is to see what actually appeared instead of the "etc. etc. etc."
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This occurs when I shut down the Tomcat Windows service...

20-Oct-2020 09:50:12.032 INFO [Thread-5] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8080"]
20-Oct-2020 09:50:12.126 INFO [Thread-5] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.catalina.loader.WebappClassLoaderBase (file:/C:/apache-tomcat-99/lib/catalina.jar) to field java.lang.Thread.threadLocals
WARNING: Please consider reporting this to the maintainers of org.apache.catalina.loader.WebappClassLoaderBase
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
20-Oct-2020 09:50:12.157 SEVERE [Thread-5] org.apache.catalina.core.StandardWrapper.unload InstanceManager.destroy() for servlet [QueryEngineServlet] threw exception
java.lang.NullPointerException
               at org.apache.catalina.core.DefaultInstanceManager.destroyInstance(DefaultInstanceManager.java:197)
               at org.apache.catalina.core.StandardWrapper.unload(StandardWrapper.java:1349)
               at org.apache.catalina.core.StandardWrapper.stopInternal(StandardWrapper.java:1632)
               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
               at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5315)
               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1441)
               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1430)
               at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
               at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
               at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
               at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:997)
               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1441)
               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1430)
               at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
               at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
               at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
               at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:997)
               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
               at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:471)
               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
               at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:791)
               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
               at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:482)
               at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
               at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
               at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
               at java.base/java.lang.reflect.Method.invoke(Method.java:566)
               at org.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:406)
               at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:495)


NOTE ~ Below also follows in the log during shutdown...looks to be thrown primarily during sleep...this warning of an open thread (same number, Thread-5) appears to be related to the destroy() NullPointerException trace above... I'm reading a mixed bag on the significance of this as it occurs only during shutdown...

20-Oct-2020 09:50:12.173 WARNING [Thread-5] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [EPS3] appears to have started a thread named [Thread-4] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.base@11.0.8/java.lang.Thread.sleep(Native Method)
org.apache.commons.pool.impl.GenericObjectPool$Evictor.run(GenericObjectPool.java:1122)
java.base@11.0.8/java.lang.Thread.run(Thread.java:834)
20-Oct-2020 09:50:12.173 WARNING [Thread-5] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [EPS3] appears to have started a thread named [Error reading Messages File.] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.base@11.0.8/java.net.SocketInputStream.socketRead0(Native Method)
java.base@11.0.8/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
java.base@11.0.8/java.net.SocketInputStream.read(SocketInputStream.java:168)
java.base@11.0.8/java.net.SocketInputStream.read(SocketInputStream.java:140)
lotus.priv.CORBA.iiop.Message.readFully(Unknown Source)
lotus.priv.CORBA.iiop.Message.createFromStream(Unknown Source)
lotus.priv.CORBA.iiop.IIOPInputStream.prefill(Unknown Source)
lotus.priv.CORBA.iiop.IIOPConnection.createInputStream(Unknown Source)
lotus.priv.CORBA.iiop.ReaderThread.run(Unknown Source)
20-Oct-2020 09:50:12.173 WARNING [Thread-5] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [EPS3] appears to have started a thread named [RecycleThread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.base@11.0.8/java.lang.Thread.sleep(Native Method)
lotus.domino.cso.RecycleThread.sleep(Unknown Source)
lotus.domino.cso.RecycleThread.run(Unknown Source)
java.base@11.0.8/java.lang.Thread.run(Thread.java:834)
20-Oct-2020 09:50:12.189 INFO [Thread-5] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-8080"]
 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you running Lotus Notes under Tomcat? And if so, have you confirmed that you are using compatible releases of Tomcat and Notes?

Also, just in case you only printed the first part of any stack traces, please also include all "Caused by" secondary traces. They are often more important than the top trace.
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It creates a connection with Notes via CORBA and DIIOP. After the session thread is created, it's thrown in the GenericObjectPool, and sleeps for ten seconds then recycled. I'm reading up on database connection pooling but I guess that it can be reused within that ten second time frame by another request. Otherwise, recycled.

What I noticed is that the Notes driver is in both the TOMCAT_HOME/lib as well as the webapp/WEB-INF/lib. Maybe since it's in TOMCAT_HOME/lib, it's persisting the connection thread (can't sleep)? Thus, can't destroy (due to NullPointerException)?

that's everything printed from the Tomcat stderr log. I can't find any Caused By in there...
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I went to localhost log and did find additional trace info, including the Caused By...


20-Oct-2020 12:28:38.582 SEVERE [Thread-5] org.apache.catalina.core.ApplicationContext.log Servlet [QueryEngineServlet] threw unload() exception

javax.servlet.ServletException: Servlet.destroy() for servlet [QueryEngineServlet] threw exception

               at org.apache.catalina.core.StandardWrapper.unload(StandardWrapper.java:1343)

               at org.apache.catalina.core.StandardWrapper.stopInternal(StandardWrapper.java:1632)

               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)

               at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5315)

               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)

               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1441)

               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1430)

               at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)

               at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)

               at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)

               at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:997)

               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)

               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1441)

               at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1430)

               at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)

               at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)

               at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)

               at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:997)

               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)

               at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:471)

               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)

               at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:791)

               at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)

               at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:482)

               at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

               at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

               at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

               at java.base/java.lang.reflect.Method.invoke(Method.java:566)

               at org.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:406)

               at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:495)

Caused by: java.lang.NoClassDefFoundError: org/apache/commons/dbcp/BasicDataSource

               at com.ptpsolutions.queryEngine.QueryEngine.close(QueryEngine.java:202)

               at com.ptpsolutions.queryEngine.QueryEngineServlet.destroy(QueryEngineServlet.java:40)

               at org.apache.catalina.core.StandardWrapper.unload(StandardWrapper.java:1331)

               ... 29 more

Caused by: java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSource

               at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1275)

               at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1104)

               ... 32 more
 
Paul Clapham
Marshal
Posts: 25946
69
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Thomas Griffith wrote:Caused by: java.lang.NoClassDefFoundError: org/apache/commons/dbcp/BasicDataSource

               at com.ptpsolutions.queryEngine.QueryEngine.close(QueryEngine.java:202)

               at com.ptpsolutions.queryEngine.QueryEngineServlet.destroy(QueryEngineServlet.java:40)

               at org.apache.catalina.core.StandardWrapper.unload(StandardWrapper.java:1331)

               ... 29 more



Looks to me like this is referring to non-Tomcat code. Do you recognize those classes?
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yeah, you're right. I'm reviewing it now. I see two separate issues related around creating JDBC DataSource objects. One servlet runs this same code but does not connect to Oracle...when instantiated, returns null for the JDBC source object. That explains the NullPointerException on the JDBC source object when close() is called (during destroy() while Tomcat is shut down...).

The second servlet creates a JDBC DataSource object. This throws ClassNotFoundException when close() is called on this object. This one I'm not getting... could the JDBC source object be garbage collected that quickly? After a request and response have occurred? Making this close() call sort of a redundant last chance close() backup?
 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Notes and CORBA??? YIKES!!!

I can only applaud your fortitude, since I'm not sure that either of those things has had any active support for over a decade. You might want to look for more modern alternatives.

No, a JAR should never appear in both TOMCAT_HOME/lib and in an application's /WEB-INF/lib. Because different classpaths are in effect depending on where in the request/response lifecycle you are, you can end up with massive corruption of static library objects. Put it in TOMCAT_HOME/lib if it's a sharable resource such as a JDBC driver JAR. If it should only be used by a single webapp instance, put it in /WEB-INF/lib.

For database connection pools, you have to put the driver JAR in TOMCAT_HOME/lib because the pool is built and owned by Tomcat itself and therefore must be in Tomcat's core classpath.
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:Looks to me like this is referring to non-Tomcat code. Do you recognize those classes?



Here's some snippets from the servlet code. Maybe that BasicDataSource cast from javax.sql.DataSource in the close() method? But that would throw a ClassCastException... but jdbcDataSource is clearly created and exists because the requests and responses are ok, and there is a previouss method which checks the JDBC connection on jdbcDataSource and that's good... I don't know what happens to jdbcDataSource when close() is called... it's apparently gone.

Or maybe jdbcDataSource is there and something changed with org.apache.commons.dbcp.BasicDataSource? Could i be missing a jar for that? I don't think so, ot seems to be a container jar...I see tomcat-dbcp.jar in TOMCAT_HOME/lib...

import javax.sql.*;
..etc...
import org.apache.commons.dbcp.BasicDataSource;
...etc....
................................

               //SQL Data Source
               private DataSource jdbcDataSource;

               //JDBC Data Source
               this.jdbcDataSource = createSQLDataSource(config.getJdbcConfig());

................................

               private DataSource createSQLDataSource(JDBCConfig jdbcConfig)

               //Get Jdbc DataSource from JNDI
               Context initCtx = new InitialContext();
               Context envCtx = (Context) initCtx.lookup("java:/comp/env");
               return (DataSource) envCtx.lookup(jdbcConfig.getDataSourceName());

................................

               public void close()
               {
                               if (this.isInServletContainer)
                               {
                                               try
                                               {
//*******************SOURCE OF NOCLASSDEFFOUND ERROR (I THINK)*****************
                                                               ((BasicDataSource) this.jdbcDataSource).close();
                                               }
                                               catch (SQLException e)
                                               {
                                                               log.error("", e);
                                               }
                               }
               }



 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry. I got distracted by the fact that this is a Notes webapp.

Tomcat supports database connection pools as plug-replaceable components. And it should be noted specifically that the default Connection Pool supplied with Tomcat changed somewhere around Tomcat 7 or 8.

However, that shouldn't have affected any webapps. because they shouldn't be accessing specific database connection pools or classes, just javax.sql.DataSource.

If you are ptpsolutions, check the QueryEngine source code (around line 202). If not - or maybe even if so - make sure that there are absolutely no database driver or connection pool classes/libraries in your /WEB-INF/lib and classes directories. And that includes DataSource! All of that stuff should be installed in Tomcat, not the webapp.

You might want to try wrapping Code tags around any further stack traces you paste in. Our forum editor went and double-spaced the lines and believe it or not, it's easier for me to read the lines when they're single-spaced!
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
wow, I see what you're saying about the double spacing. I was pulling out "highlights" from the code so wasn't sure if that would be more confusing with the code tag and scroll boxes.

Yeah, line 202 is that cast and close() call in the close() method...



one of the objects is throwing the NoClassDefFound exception... but it seems like everything should be there...

jdbcDataSource... verified connectivity and used for SQL operations
BasicDataSource... tomcat-dbcp.jar exists in TOMCAT_HOME/lib

I have no idea what can't be found here.

 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The webapp should NEVER close the datasource. It should only close Connections. The DataSource is "opened" by Tomcat and Tomcat will "close" it when Tomcat shuts down. The Datasource is a Pool, and when you close a Pool Connection, the JDBC Connection that it fronts is returned to the pool for re-use. But again, you do not close the Pool itself.
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The only explicit data pool in the app is the Domino data source pool (there isn't one for the jdbcDataSource). Does DataSource implicitly create a data pool in the container?
 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, but I'm talking about JDBC Connection Pools here and they are never created in the webapp, only withing the webapp server. That is done by defining one or more Connection Pools (DataSources) in either the TOMCAT_HOME/conf/server.xml file if it's a pool shared between webapps or in the webapp's Context xml file if the pool is used only by a single webapp.

I never got far enough into Domino to know whether they used this sort of pooling or not. If they created a non-JDBC/NoSQL Notes database pool internal to the webapp, then none of what I said up tp now means much, and you have a whole different sort of problem. One that probably would require contacting Notes Technical Support.
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ok, yes, the DataSource for jdbcDataSource is specified within the app context file (conf/Catalina/localhost), so the container implicitly creates a pool from that? When the servlet is first called...or maybe at startup? This DataSource (jdbcDataSource)  is a connection to Oracle...

The corresponding close() on the Notes DataSource doesn't throw an error.
 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
At startup and periodically thereafter Tomcat scans certain locations to detect deployment (or re-deployment) of webapps. When it sees an XML file in /TOMCAT_HOME/conf/Catalina/localhost, for example, Tomcat will open that file and feed it to Tomcat's XML digester, which converts the XML text into corresponding JavaBeans that are then used as the driving data for deployment.

In particular, the DataSource(s) defined in the Context are used to manufacture one or more database connection pools (which are themselves JavaBeans) and those pools are then cataloged into Tomcat's JNDI directory for the webapp that's being deployed. So that the webapp can then find the DataSource in question via a JNDI lookup. This is done far in advance of any servlet init code or webapp request handing.

Likewise, the DataSource only gets destroyed after the webapp has been undeployed (for example, when Tomcat shuts down),

I wouldn't call this "implicit", since all the parameters in question are in plain view in the Context, but it is automatic. So, as I said, the application code should not be mucking around with it.. All the application should be doing is locating the DataSource (again, via JNDI), obtaining Connections from the DataSource, then closing those Connections (returning them to the DataSource) as quickly as possible. Note that this means you shouldn't hold onto Connections for very long periods of time and should never store them in Session  Scope variables.
 
Thomas Griffith
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I see, DataSource stores the reference(s), or "pointers"?, to the database (found in the context file) in a "bean pool" which then pulls one out when a servlet creates (and soon, closes) a connection (for SQL operations).

The DataSource pool is destroyed when Tomcat is shutdown.

The case on line 202 is to BasicDataSource. That's not in javax.sql but imported via org.apache.commons.dbcp.BasicDataSource. Could that be the java.lang.NoClassDefFoundError?
 
Tim Holloway
Saloon Keeper
Posts: 22648
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
More precisely, a DataSource implements the Factory Design Pattern. On request, it dispenses JDBC Connections.

Internally, the DataSource uses something akin to the DriverManager.getConnection() method to obtain a fixed number of Connection objects when it initializes. When a client requests a Connection, the DataSource then constructs and returns a Fa├žade Connection that exactly imitates the Driver Connection except that its close() method returns the Connection to the pool.

A DataSource - I'll just call it a Pool/Connection Pool hereafter - starts with a fixed number of Connections. If a client requests a Connection and all of the Pool's Connections are already assigned, then the Pool can use DriverManager.getConnection() again to obtain a new Connection and return that one instead. It's more resource-expensive than using a pre-constructed Connection, of course.

To avoid runaway Connection-grabbing, there's an upper limit, however, so that if you attempt to obtain too many Connections, subsequent requests will fail until at least one Connection has been returned to the Pool. Often Connections returned after the pool minimum number of Connections have been returned get destroyed, but that depends on the particular Pool implementation and configuration options.

Details of all this may vary depending on which DataSource implementation you are using and what configuration parameters you supply (and in some cases can even be altered at runtime). It's the basic mechanism - Factory for Connection objects - that's the essential part.

Note that all of the Connections in a Pool are supposed to be interchangeable. Thus, when you obtain a Connection, you should set whatever specific properties it needs (such as Auto-Commit) without assuming that the Connection is in the proper state. In some cases, the process of returning a Connection to a Pool may reset certain Connection properties, but you should always check the documentation for the Pool implementation that you are using.
 
I didn't do it. You can't prove it. Nobody saw me. The sheep are lying! This tiny ad is my witness!
the value of filler advertising in 2020
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic