Frustrated with configuring Tomcat v8 jdbc pool for Oracle 19c - oracle

We have an older application on Linux Tomcat v8, connecting to Oracle 19c database using Oracle 19c jdbc client library ojdbc8.jar and having trouble getting the right datasource settings in context.xml
Much of the online resources I've found are contradictory, but this is where I'm at right now:
<Resource
name="jdbc/myDatasource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#ldap://{LDAP_HOST}:389/{DBNAME},cn=OracleContext,dc={DOMAIN},dc=com"
username="*********"
password="*********"
maxTotal="50"
maxIdle="10"
connectionProperties="oracle.jdbc.ReadTimeout=5000"
/>
But I'm not trusting that we're using the right factory, since the classloader logging shows this:
[Loaded org.apache.tomcat.jdbc.pool.DataSourceFactory from file:/opt/apache-tomcat/apache-tomcat-8.5.31/lib/tomcat-jdbc.jar]
[Loaded org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory from file:/opt/apache-tomcat/apache-tomcat-8.5.31/lib/tomcat-dbcp.jar]
Feb 01, 2023 11:30:50 AM org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory getObjectInstance
Feb 01, 2023 11:30:53 AM org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory getObjectInstance
Feb 01, 2023 11:30:53 AM org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory getObjectInstance
It seems like the right factory gets loaded, but then the basic/default factory is being used to create the pools instead of the Tomcat DataSourceFactory. Am I reading this wrong?
Any pointers that I should look for? I'm scanning the application contents under /webapps to see if they have any embedded jdbc pools being created, but so far haven't found anything.
We're not trying to do anything fancy, we just want the basic/right/normal settings to start with for this connection scenario. All the settings we have now were passed down from previous Tomcat & Oracle versions, so everything is suspect.
Edited to add:
I found this buried in the application code, and when I comment it out I can see the "Basic" DataSourceFactory is no longer loaded, and the messages about the getObjectInstance are gone.
<resource-ref id="ResourceRef_1200664413729">
<description>data source</description>
<res-ref-name>jdbc/masked-name</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
But now if I specify the Tomcat factory for my context.xml datasources:
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
then we get bad pool behavior in a failover situation. The pool appears to get corrupted when one DB node goes down, requiring a restart.
But if I specify no factory, then the log again shows the DB2 BASIC factory being used, yet things seem to work right for failover.
So I don't understand why all the online documents seem to want me to use the Tomcat datasource factory. What's "right" ?

Related

SQL DB sessions leakage issue on tomcat 9.0.43

we are upgrading our application from tomcat 9.0.22 to 9.0.43 version. but we are struggling with session leakage issue on tomcat 9.0.43. we have same configuration for JDBC connection but no idea why database sessions not releasing on tomcat 9.0.43. but application works fine on 9.0.22 version. kindly help upgradation must required as there is vulnerability find by InfoSec. below is configuration for JDBC connection. application hosted on windows server 2019 and SQL standard edition
<Resource name="jdbc/abcDb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sqlserver://10.xxx.xxx.xx:1433/Prod"
username="xxxx"
password="XXXXXXXXX"
maxWaitMillis="40000"
maxTotal="1000"
maxIdle="233"
minIdle="89"
timeBetweenEvictionRunsMillis="68000"
minEvictableIdleTimeMillis="110000"
validationQuery="SELECT 1"
testWhileIdle="true"
testOnReturn="true"
testOnBorrow="false"
removeAbandonedOnBorrow="true"
removeAbandonedOnMaintenance ="true"
logAbandoned="false"
removeAbandonedTimeout="55" />

Oracle DB connections not releasing from connection pool in Tomcat 8

We are migrating Tomcat6, java 6 and Oracle 10g web-applications to Tomcat 8, Java 8 and Oracle 10g. Our applications working fine after migrated, but initial connections (initialSize="5") available in connection pool not released after Tomcat shut down. When second time starting tomcat, its creating 5 more initial connections to pool. I am using below resource configuration in server.xml
<Resource name="TestAppDataSource"
auth="Container"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
initialSize="5"
maxActive="40"
maxIdle="40"
minIdle="5"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="30000"
maxWait="10000"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1 from dual"
validationInterval="30000"
logAbandoned="true"
removeAbandonedTimeout="30"
removeAbandonedOnBorrow="true"
removeAbandonedOnMaintenance="true"
suspectTimeout="300"
maxAge="60000"
url="jdbc:oracle:thin:#//IP_ADDRESS:1521/SCHEMA_NAME"
username="USER_NAME"
password="PASSWORD" />
And below resource link configuration in application META_INF/context.xml
<ResourceLink
name="APP_TEST"
global="TestAppDataSource"
type="javax.sql.DataSource"
/>
I am using ojdbc7.jar for oracle driver. Please help whether i missed any configuration..
try with the follow option:
removeAbandoned = true
(boolean) Flag to remove abandoned connections if they exceed the
removeAbandonedTimeout. If set to true a connection is considered
abandoned and eligible for removal if it has been in use longer than
the removeAbandonedTimeout Setting this to true can recover db
connections from applications that fail to close a connection. See
also logAbandoned The default value is false.
Tomcat now use JDBC Connection Pool org.apache.tomcat.jdbc.pool that is a replacement or an alternative to the Apache Commons DBCP connection pool.
removeAbandoned is a option for JDBC Connection Pool
https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html
You have to add closeMethod="close" to your JDBC resource in context.xml. That way, Tomcat properly releases pending connections to the database.
Nitpick: when tomcat is shut down, the JVM is shut down, hence all of its resources are "released" too, and there is no more connection pool - what you meant is that the connections are not properly being shut down, so the DB is not being notified that they're closed, and hence the sessions there are not being ended. This is either because the pool is not getting a shutdown command, or because something else is hanging in tomcat during shutdown and hence it's not getting to the point of shutting down the pool, being force-killed by the shutdown script after a wait timeout has expired. You can take thread dumps during shutdown to see what it's waiting on, and look at catalina.out for messages about leaked threads (...has started a thread ... that's not been shut down ...). It is a common problem that webapps will launch long-running threads without daemonizing them - such webapps need to implement a ServletContextListener that will stop this thread/resource when the ServletContext is stopped.

Tomcat 8 Slow startup with deployWAR

I went from Tomcat 7.0.54 to 8.0.15, upgraded openSSL to 1.0.1k and tcnative to the latest 1.1.32 with APR 1.5.1.
However, Tomcat now starts about 2 to 3 times slower than before. Most noticeably, it takes alot longer to deploy WAR files.
Tomcat 7
Jan 20, 2015 3:39:36 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive <PATH>\file.war has finished in 433 ms
Tomcat 8
Jan 21, 2015 2:27:01 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive <PATH>\file.war has finished in 4,310 ms
This happens to all WAR files, all went from milliseconds to around 5 seconds.
I removed the JasperListener from the server.xml because it appears to have been removed.
unpackWARs="false"
autoDeploy="true"
unpackWars does not make a difference if set to true (atleast not noticable).
I thought it might have been the annotation scanning issue fixed in 8.0.17, but no luck.
I noticed that jarsToSkip in catalina.properties changed from
tomcat.util.scan.DefaultJarScanner.jarsToSkip to
tomcat.util.scan.StandardJarScanFilter.jarsToSkip
and that
org.apache.catalina.startup.TldConfig.jarsToSkip was removed and went to context.xml
<JarScanner>
<JarScanFilter tldSkip="websocket-api.jar,tomcat-websocket.jar"/>
</JarScanner>
However, none of this seems to bring me back to the performance of tomcat 7. The one action that did do it, was removing the websocket jars. However we need them. This brings me to the conclusion that they are still scanned, even though they should be skipped.
Am I missing something? Does the context.xml not do the same as the catalina.properties jarsToSkip?
The solution for slow startup in general for me was to put
in conf/context.xml:
<Context>
<JarScanner>
<JarScanFilter defaultPluggabilityScan="false" />
</JarScanner>
</Context>
Source:
https://groups.google.com/a/apereo.org/forum/#!topic/sakai-dev/cjtYGxd6hG0
EDIT Oct-2022:
Adding a scanManifest="false" attribute to <JarScanner> tag may speed up the loading process even further:
<JarScanner scanManifest="false">
<JarScanFilter defaultPluggabilityScan="false" />
</JarScanner>
Are you sure unpackWARs="true" is not making a difference for you?
There's an ongoing discussion about this topic in bugzilla:
https://issues.apache.org/bugzilla/show_bug.cgi?id=57251
There it has been established that Tomcat 8's behaviour when unpackWARs="false" will be noticeably slower because of an implementation simplification performed in the code.
I am having similar problems here.
One option that improved the startup time was to add:
metadata-complete="true"
to the web.xml (webapp element), as recommended in https://cwiki.apache.org/confluence/display/TOMCAT/HowTo+FasterStartUp. This assumes your web.xml is all what your web-app needs to boot.
It didn't totally fix the issue for me, but startup speed improvement was substantial.
you can try parallelism for startup by changing
in conf/server.xml
host element attribute <Host ... startStopThreads="0"/>

Worklight 6.0 does not start on Liberty - HSQLDB

I have followed the infocenter docs to setup Worklight on Liberty and Oracle Database all on Windows 2008.
(http://pic.dhe.ibm.com/infocenter/wrklight/v6r0m0/topic/com.ibm.worklight.help.doc/devref/t_transporting_apps_and_adapters.html - Deploying IBM Worklight applications to test and production environments)
When I start the liberty server, I get this error on the browser
Exception thrown by application class 'com.worklight.core.auth.impl.AuthenticationFilter.doFilter:110'
javax.servlet.ServletException: Worklight Project not initialized
at com.worklight.core.auth.impl.AuthenticationFilter.doFilter(AuthenticationFilter.java:110)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:194)
at [internal classes]
Going thru the logs, it shows it did not start because the HSQLDB driver is not found.
The server.xml has the following:
<application id="finance" name="finance" location="finance.war" type="war">
<classloader delegation="parentLast">
<commonLibrary>
<fileset dir="${shared.resource.dir}/worklight/lib" includes="worklight-jee-library.jar"/>
</commonLibrary>
</classloader>
</application>
<library id="worklight/OracleLib">
<fileset dir="${shared.resource.dir}/worklight/oracle" includes="*.jar"/>
</library>
<!-- Declare the IBM Worklight Console database. -->
<dataSource jndiName="worklight/jdbc/WorklightDS" transactional="false">
<jdbcDriver libraryRef="worklight/OracleLib"/>
<properties.oracle driverType="thin" URL="jdbc:oracle:thin:#localhost:1521:ORCLWL" user="WORKLIGHTDIS" password="WORKLIGHTDIS"/>
</dataSource>
I took a step further and checked how the WAR file links to database jndi entries. Going thru the web.xml file I found this:
<resource-ref>
<description>Worklight Server Database</description>
<res-ref-name>jdbc/WorklightDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
The res-ref-name is slightly different from what is declared in the server.xml. Bear in mind that these entries were created by the ant script. This seems to be inconsistent from what the war file contains (created by the WL Studio).
Anyway I gave it a try and changed the server.xml jndi entry to be exactly the same as the web.xml entry (jdbc/WorklightDS). When I restarted the liberty server It did not change the final result at all. The error message and the HSQL driver thing kept showing in the log.
This is the exception
nested exception is java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.hsqldb.jdbcDriver not found in Worklight platform or project /finance
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275)
Later on I found out that if I change the element in the server.xml to be worklight value for all atributes it works. How odd it is.
<application id="worklight" name="worklight" location="finance.war" type="war">
Please, any help is much appreciated to help me understand and fix it.
The error message "java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.hsqldb.jdbcDriver not found in Worklight platform or project ..." is indeed misleading. It should better read something like "Worklight server cannot be started because no data-source is bound to resource reference: 'jdbc/WorklightDS'. Re-configuring the server will solve this problem. for more information search for "Creating and configuring the databases" in IBM Worklight information center."
The explanation for the error message is that by writing <application id="finance" name="finance" location="finance.war" type="war"> you selected a context root /finance, according to the WebSphere Liberty rules at Deploying a web application to the Liberty profile. For this context root, you need to write
<dataSource jndiName="finance/jdbc/WorklightDS" transactional="false">
This is similar to how JNDI environment entries need to be declared for Worklight (see here).

iBatis 3 - JNDI configuration example

The iBatis framework has been significantly tweaked between versions 2 & 3, so much that even the config file (now often referred to as MapperConfig.xml) is different.
That being said, there are lots of examples online on how to create a JDBC connection pool with iBatis, but I couldn't find one example on how to do it with JNDI. There is an updated user guide at: http://svn.apache.org/repos/asf/ibatis/java/ibatis-3/trunk/doc/en/iBATIS-3-User-Guide.pdf which does refer to the JNDI settings on page 19, but I still couldn't it get it correctly communicate with the database.
A working example of a JDNI (container managed connection pool) in iBatis 3 would be greatly appreciated!!
Assuming you've already got a JNDI database resource set up, the following environment for iBatis 3's configuration XML file works for me (running on Tomcat):
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/webDb"/>
</dataSource>
</environment>
This is what I have in my config file, works well in Glassfish and WebSphere:
<dataSource type="JNDI">
<property name ="data_source" value="jdbc/cpswebmon"/>
</dataSource>
"jdbc/cpswebmon" is the JNDI resource name on my application server

Resources