<sql:setDataSource var="TCIT" scope="application"
driver="${driver}"
url="${url}"
user="${username}"
password="${password}" />
The above code is used in a legacy application deployed in OC4J that is being migrated to WebSphere 8.5. The properties in {} above are fetched from a property file. Ensured the values are coming correctly form there. However, when the database connection is created the application is encountering the following exception: Unable to get connection, DataSource invalid: "java.sql.SQLException: No suitable driver" . I have the ojdbc14.jar in the WEB-INF/lib folder, still facing the issue.
Finally the issue got resolved creating a JDBC connection pool at Application server level. Turns out Websphere does not allow the connection to be created using the above method. Below is the modified tag that is using JNDI lookup for accessing the JDBC connection pool at application level.
<sql:setDataSource var="connPool" scope="application" dataSource="${jndi.devPool}"/>
Related
I'm unclear on the appropriate way to set up connections to an Oracle RAC database in Tomcat via context.xml. THIS method works for me:
<Resource
name="jdbc/mydb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:<connection details>"
username="<username>"
password="<account>"
maxTotal="150"
maxIdle="10"
/>
But is that using a connection pool? I tried adding factory="org.apache.tomcat.jdbc.pool.DataSourceFactory", as suggested at https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html, and mysteriously with that one change, I started getting:
java.sql.SQLException: ORA-01017: invalid username/password; logon denied
If I instead try type="oracle.jdbc.pool.OracleDataSource" and factory="oracle.jdbc.pool.OracleDataSourceFactory" I get:
Error: Unable to obtain a JDBC connection from Datasource:
java.lang.Exception: Error: Unable to obtain a JDBC connection from Datasource:
I've looked all over, but it's not clear to me what the best practice is for this. Ideas?
I am adding this answer to clarify my earlier comments, and for future visitors to this question.
Summary
Both of the following approaches will use DB connection pools:
Use Tomcat's newer, default DBCP 2 pool with type="javax.sql.DataSource".
Use Tomcat's older JDBC pool with factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" and type="org.apache.tomcat.jdbc.pool.DataSource".
I don't know enough about the differences to give any strong recommendations re. using one over the other.
The Default DBCP 2 Tomcat Pool
To make use of the default Tomcat DB connection pool, via a JNDI resource, you should follow the instructions provided on this Tomcat documentation page: JNDI Datasource How-To
Specifically, you need to use type="javax.sql.DataSource".
Here is a very basic resource configuration - not suitable for production, but useful to illustrate the approach. And it's for MySQL not Oracle, so there will be some adjustments needed:
<Resource name="jdbc/my_db"
auth="Container"
type="javax.sql.DataSource"
initialSize="5"
username="db_user"
password="***"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mytestdb" />
When using initialSize="5", I saw the 5 expected connections on the DB server.
In the JVM, a connection pool was created - as shown in this VisualVM heap dump:
Here we can see that the pool is created, it has 5 connection objects, and it is using Tomcat DBCP - which, in turn, is a fork of Apache Commons DBCP 2.
DBCP 2 provides support for JDBC 4.1.
Tomcat's Home-Grown JDBC Pool
If you look at the Tomcat documentation on this other page - The Tomcat JDBC Connection Pool - you will see different guidance.
Specifically it states that you need both of the following in your <Resource>:
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
type="org.apache.tomcat.jdbc.pool.DataSource"
If you use this, you will also be using a DB connection pool - but it will be based on the older Tomcat JDBC pool package:
In this example, I used initialSize="3".
In the Tomcat documentation this is presented as "a new connection pool" (it was a replacement for the previously used Commons DBCP 1.x). It's not as new as the Tomcat default DBCP 2 solution. I think the documentation wording is out-of-date, now. And somewhat confusing, because of that.
Additional Notes
Notes from a member of the Tomcat commit team (see here):
Tomcat JDBC is Tomcat's "home grown" database connection pooling and does not use poolPreparedStatements
Tomcat DBCP is Tomcat's package renamed fork of Apache Commons DBCP 2.
Tomcat DBCP is used by default.
You can always choose to implement a pool directly in your code, without using a JNDI <Resource> annotation. There are many available options.
(In my initial tests, there was a problem with my Tomcat installation which resulted in the creation of too many connections for DBCP 2. That misled me, initially).
Oracle Universal Connection Pool (UCP) is a Java connection pool that you can use as well. It is feature rich and works well with Oracle RAC, DG etc., Check out UCPServlet for an example.
What I intend to do is access remote queues in Oracle Weblogic JMS (version 10.3.4) from a spring application deployed in Tomcat7.
For this I am trying to configure a Resource (eg JMS connection factory, queues etc) in Tomcat's context.xml file. Then access this resource using jndi lookup in the spring configuration file and provide it to the necessary beans. I have already created connection factory and queues in Weblogic JMS and they can be accessed using jndi names.
I am able to make it work successfully when using ActiveMQ instead of Weblogic JMS. However with Weblogic JMS, I am facing an issue with configuring the Resource element. I am not sure what attributes to be used with Resource tag while connecting to Oracle Weblogic JMS.
When working with ActiveMQ the resource element config looks like below
<Resource name="jms/MyConnectionFactory" auth="Container"
type="org.apache.activemq.ActiveMQConnectionFactory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
description="JMS Queue Connection Factory"
brokerURL="tcp://localhost:61616" brokerName="MyActiveMqBroker"/>
I am struggling to find the configuration to be used with Oracle Weblogic JMS. I have gone through documentations to see how to do it but with no luck.
Any help or pointers would be highly appreciated.
Thanks.
I am using the IBM WebSphere Application server v8.5 Liberty Profile. I have enabled the feature jndi-1.0 in server.xml by adding
<feature>jndi-1.0</feature>
But still I get the error "An attempt was made to retrieve an initial context for [ClassName] but no JNDI feature is configured."
Any idea what I may be doing wrong?
In my web application I am using hibernate & spring. The Hibernate SessionFactory object is being injected as a spring bean at the time of tomcat server start up. Normally it is working fine. But the problem arises when I shut down or even restart my database.
After restarting my database if I retrieve a session from Hibernate SessionFactory object and want to execute query i am getting org.hibernate.exception.JDBCConectionException: Could not execute query exception.
To overcome this problem I need to restart the tomcat server. After restart it creates the new SessionFactory object, so I don’t get the exception.
In a situation how can I get a new fresh connection with the database, so that I don’t need to restart the server again & again.
SessionFactory rebuild worked for me
Our app is using tomcat, hibernate(3.5.1) and Oracle db (there are actualy two instances - one is the main for the application and the second one - remote)
sometimes remote db restarts, after that exception occurs on each call
JDBCConnectionException:could not execute query
Caused by: SQLRecoverableException: No more data to read from socket
Fistly I added to configuration
hibernate.dbcp.validationQuery=select 1 from dual
hibernate.dbcp.testOnBorrow=true
hibernate.dbcp.testOnReturn=true
but without result.
Then I tried to close sessions and recreate it.
Finally what worked for me - after this exeption
sessionFactory recreate
sessionFactory.close();
sessionFactory = annotationConfiguration.buildSessionFactory();
This is not really Spring or Hibernate related. What you need to do is to setup your JDBC connection pool to test connections before returning them to whoever needs them (e.g. Hibernate). If the pool discovers that the connection in the pool is broken, it dicards it and tries another one from the pool. If all connections in the pool are broken, the pool will try to create new ones. Everything is transparent and your application won't even notice.
Which connection pool you use? In dbcp set validationQuery to"SELECT 1" nd consider setting: testOnBorrow=true, testOnReturn=true and testWhileIdle=true. For c3p0 check out the documentation.
I have a problem concerning with proxool and oracle driver in Tomcat.
The web application I use contains a webservice jar file using metro and a servlet to initialize / start the proxool pool. The proxool pool is configured with an oracle connection. When the service is called, it fetches a connection from the pool, executes a statement and returns. I close the resultset, the statement and the connection in the service method afterwards.
When I now try to hot undeploy the web application, the servlet stops proxool pool by ProxoolFacade.shutdown(); in it's destroy method.
The problem is, that the hot undeploy can not finish because the Oracle driver ojdbc5.jar can not be deleted from the folder of the extracted web application.
Trying the same with a SQL server database and the jtds driver it works without this problem.
Used versions:
Apache Tomcat 6.0.18
Oracle 11g JDBC driver 11.1.0.6.0
Proxool 0.9.1
Anyone has an idea?
Regards Timo
You must add the Oracle driver to the Tomcat instance and configure Tomcat JNDI with an Oracle datasoure.
This way, the driver will stay alive when the app is terminated and Tomcat will control the pooling of the DB connections. The reason for your problem is that some DB drivers "hook" into the VM. This means that Tomcat can't unload the classes during redeploy -- there are still references around.
I'd even suggest to try to move proxool into the Tomcat server and have Tomcat manage the pools for you. That would make hot deploy much faster and more reliable, even if you leak connections.