2

I am using JNDI + HikariCP on Tomcat 9.0.7 with the following configuration :

 <Resource name="jdbc/mydb" auth="Container"
      factory="com.zaxxer.hikari.HikariJNDIFactory"
      type="javax.sql.DataSource"
      minimumIdle="5" 
      maximumPoolSize="20"
      connectionTimeout="300000"
      dataSourceClassName="com.microsoft.sqlserver.jdbc.SQLServerDataSource"
      dataSource.url="jdbc:sqlserver://server:1433;databaseName=mydb"      
      dataSource.user="fantomas"
      dataSource.password="somepassword" 
      closeMethod="close"
      />

When I run tomcat without any of my WAR deployed (just standard installation, nothing more), I have the following WARNING in Catalina log:

09-May-2018 10:15:16.971 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [host-manager] appears to have started a thread named [mssql-jdbc-TimeoutTimer-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 sun.misc.Unsafe.park(Native Method)
 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
 java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
 java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
 java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 java.lang.Thread.run(Thread.java:748)

What is wrong and why there is a leak ? How can I fix it ?

UPDATE-1 Custom libraries in ./lib of Tomcat installation are:

ms-sql-6.4.0.jre8.jar 
slf4j-api-1.7.25.jar 
HikariCP-2.7.8.jar 

UPDATE-2 Same problem also with Hikari 3.1.0 & Tomcat 9.0.8

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
kulatamicuda
  • 1,603
  • 2
  • 21
  • 40

2 Answers2

3

The thread in question (mssql-jdbc-TimeoutTimer) belongs to the MSSQL driver. It shows up when you use HikariCP, but not Tomcat JDBC, because HikariCP appropriately uses JDBC timeout APIs for reliability.

This is a known issue with the MSSQL driver, search for 'mssql-jdbc-TimeoutTimer' here.

It seems that the timer is started by HikariCP's call to the MSSQL driver implementation of Connection.isValid(). So, you may be able to avoid the issue by setting a connectionTestQuery, which will disable the use of isValid().

brettw
  • 10,664
  • 2
  • 42
  • 59
  • Thanks, tested with connectionTestQuery="SELECT 1" on Tomcat 9.0.8 and works. – kulatamicuda May 24 '18 at 12:45
  • Can anyone figure out which the actual Github issue is? Possibly this one, but it's marked as solved. https://github.com/Microsoft/mssql-jdbc/issues/150 – Jeff Evans Oct 10 '18 at 02:56
0

Related issue with similar leak reported to hikari and it seems that the final solution doesn't use Hikari JNDI factory but Tomcat's Datasource

Try to change the factory to:

factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

EDIT

You created a new issue for Hikari

Ori Marko
  • 56,308
  • 23
  • 131
  • 233