How to get PoolingDataSource from Tomcat's JNDI - java

If I deploy a web app to Tomcat, and have code like this:
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/myDB");
How can I specify for this DataSource to be a PoolingDataSource? How do I configure the pool (GenericObjectPool) to inject the PoolingDataSource with?
Or, is this the default behavior of Tomcat's JNDI implementation? Thanks in advance!

Just configure the connection pool settings (maxActive, maxWait, maxIdle, ...).
Tomcat comes with the apache commons-dbcp library. It is repackaged as $CATALINA_HOME/lib/tomcat-dbcp.jar.
Take a look at the tomcat doc for details: http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html#Database_Connection_Pool_%28DBCP%29_Configurations
<Context>
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest"/>
</Context>

The JDBC Connection Pool org.apache.tomcat.jdbc.pool
is a replacement or an alternative to the commons-dbcp
connection pool.
Add to the server.xml file in the GlobalNamingResources section something like the next:
<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="root"
password="password"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mysql"/>
Add the JDBC driver JAR into the Tomcat lib directory.
Add in your context.xml:
<ResourceLink global="jdbc/TestDB" name="jdbc/TestDB"
type="javax.sql.DataSource"/>
See more in The Tomcat JDBC Connection Pool.

Related

Posting a request throws Connection pool error in java

I'm getting connection pool issue when I try to post to the Database
here what I'm using for context xml file
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
maxActive="10"
initialSize="0"
maxAge="1800"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="18000"
jmxEnabled="true"
fairQueue="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
the Error:
Caused by: org.apache.tomcat.jdbc.pool.PoolExhaustedException: [ajp-nio-0.0.0.0-8009-exec-3] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[size:10; busy:10; idle:0; lastwait:30000].
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:710) ~[tomcat-jdbc.jar:?]
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:198) ~[tomcat-jdbc.jar:?]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:132) ~[tomcat-jdbc.jar:?]
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:157) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
I have this working working before, then suddenly it stops working, Is there something I'm missing to add or update in my config?
There can be different reasons why your connectionpool is exausted. If you are using a framework that connects to your mysql database check the recommended pool configuration.
Also make sure to close your connections properly.
The try-with-resources Statement: try with resources
a reasonable config could look like this:
<Resource type="javax.sql.DataSource"
...
initialSize="10"
maxActive="100"
maxIdle="50"
minIdle="10"
...
/>

MySql ReplicationDriver - Tomcat won't start when slave is down

Here is my tomcat context.xml file with my config for MySql (1 master / 1 read replica).
<Resource auth="Container"
driverClassName="com.mysql.jdbc.ReplicationDriver"
defaultAutoCommit="false"
initialSize="3"
logAbandoned="false"
maxActive="200"
maxIdle="10"
maxWait="10000"
name="jdbc/powerptc"
removeAbandoned="true"
testOnBorrow="true"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
username="username"
password="password"
url="jdbc:mysql:replication://localhost:3306,2.2.2.222:3306/mydb?autoReconnect=true&allowSlaveDownConnections=true&readFromMasterWhenNoSlaves=true&connectTimeout=15000&socketTimeout=15000"
validationQuery="/* ping */ SELECT 1"/>
My issue is when the slave (2.2.2.222) is down, I tomcat won't start. I was hoping to configure it so that tomcat would still start with a slave down, and just use the master for all queries is this possible?

Reading tomcat server.xml in junit test case

I am using java 7, and tomcat 7. I am writing few tests for my application in jUnit which uses tomcat/conf/server.xml for jndi. Here is the maven suggest folder structure.
src
|___test
|___java
| |___Testcase.java
|___resources
|___conf
|___server.xml
My sample server.xml would look like this,
<Resource name="jdbc/junit_db"
type="javax.sql.DataSource"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/junit_db?zeroDateTimeBehavior=round&autoReconnect=true&dumpQueriesOnException=true"
username="root"
password="password"
maxIdle="0"
minIdle="0"
initialSize="1"
maxWait="5000"
maxActive="50"
loginTimeout="1000"
minEvictableIdleTimeMillis="2000"
timeBetweenEvictionRunsMillis="5000"
validationQuery="SELECT 1"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="false"
logAbandoned="true"
removeAbandoned="true"
poolPreparedStatements="true"
maxOpenPreparedStatements="10000"
accessToUnderlyingConnectionAllowed="false"
defaultAutoCommit="false"
defaultReadOnly="false"
defaultTransactionIsolation="4"/>
<Resource name="jdbc/junit_hive_db"
type="javax.sql.DataSource"
factory="com.office.hive.HiveDataSourceFactory"
driverClassName="org.apache.hive.jdbc.HiveDriver"
url="jdbc:hive2://localhost:10000/default?zeroDateTimeBehavior=round"
username=""
password="" />
I want to load this server.xml into the IntialContext before running jUnit test cases. How to achieve this?
Followed this link, it has solution for loading jndi into initialcontext manually.
http://www.alexecollins.com/tomcat-context-junit-rule/
Give TomcatJNDI a try. When fed with Tomcat's configuration files it will deliver all JNDI based objects that are declared in these files as soon as they are looked up. The code to achieve this is for example
TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processServerXml(serverXmlFile)
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.start();
Then you can lookup the objects as you are used to:
DataSource ds = (DataSource) InitialContext.doLookup("java:comp/env/path/to/datasource")
More about TomcatJNDI can be found here.

Tomcat need to restart after database restart

I have a webapp deployed in Tomcat 7. There I cave configured my database pool as given below.
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource type="javax.sql.DataSource"
name="jdbc/TEST"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testdb?zeroDateTimeBehavior=convertToNull"
username="test"
password="test"
initialSize="10"
maxActive="100"
maxIdle="50"
minIdle="10"/>
This configuration works fine.But I want to configure my database pool to reconnect data database server automatically when a database server down for sometime and started again.
Try to add
?autoReconnect=true
in your url.
I found an answer for this problem. Below configuration done the job.
<Resource type="javax.sql.DataSource"
name="jdbc/TEST"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testdb?zeroDateTimeBehavior=convertToNull"
validationQuery="select 1"
validationInterval="30000"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
username="test"
password="test"
initialSize="10"
maxActive="100"
maxIdle="50"
minIdle="10"/>

Mysql not reconnecting with JNDI Tomcat 6

I am using JNDI with Tomcat6 to manage Mysql connections, my Catalina/domain.com/ROOT.xml has:
<Resource name="jdbc/db" auth="Container" type="javax.sql.DataSource"
username="db1" password="somepass" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/db?autoReconnect=true" maxActive="15" maxIdle="3"
maxWait="5000" removeAbandoned="true" removeAbandonedTimeout="20" />
I though autoReconnect will do the job reconnecting to database but it does not, after about 8 hours of inactivity my app spits out lost connection to database errors. Any ideas?
Thanks, Fedor
Dont use autoReconnect. There are problems with it and it's been deprecated. For example, you could have a disconnect/reconnect event happen while a thread is using the connection. I would instead have your connection pool test connections with testOnBorrow before passing them to the app. Here is an example:
<Resource name="jdbc/db"
auth="Container"
type="javax.sql.DataSource"
username="db1"
password="somepass"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/db"
maxActive="15"
maxIdle="3"
maxWait="5000"
removeAbandoned="true"
removeAbandonedTimeout="20"
logAbandoned="true"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
validationQuery="select 1"
minEvictableIdleTimeMillis="3600000"
timeBetweenEvictionRunsMillis="1800000"
numTestsPerEvictionRun="10"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
/>

Categories

Resources