Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to use JNDI DataSource provided by Tomcat in Spring?

I want to use JNDI DataSource provided by Tomcat in Spring based application. I use Tomcat 7 pool. Tried to configure as described here.

Configured server.xml of Tomcat:

  <GlobalNamingResources>
    <Resource name="jdbc/ApsuserAtAzistst"
              auth="Container"
              type="org.apache.tomcat.jdbc.pool.DataSource"
              driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@10.0.153.10:1525:AZISTST"
              username="APSUSER"
              password="PASSWORDOFAPSUSER"
              initialSize="1"
              minIdle="1"
              maxIdle="1"
              maxActive="3"
              maxWait="1000"
              validationQuery="select 1 from dual"
              jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport(threshold=1500)"
            />
  </GlobalNamingResources>

created META-INF\context.xml with content:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <ResourceLink name="jdbc/ApsuserAtAzistst"
                  global="jdbc/ApsuserAtAzistst"
                  type="org.apache.tomcat.jdbc.pool.DataSource"/>
</Context>

and configured applicationContext.xml

<beans profile="dev,test,default">
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/ApsuserAtAzistst"/>
    </bean>
</beans>

When I run applcation I receive an error:

SEVERE: Exception processing Global JNDI Resources
javax.naming.NamingException: Cannot create resource instance
    at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:146)
    at javax.naming.spi.NamingManager.getObjectInstance(Unknown Source)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:843)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
    at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:119)
    at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:73)
    at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:36)
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:140)
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:147)
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:112)
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:84)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:402)
    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:347)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:725)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:684)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:456)

Everything works when I change applicationContext.xml to:

<beans profile="dev,test,default">
    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@10.0.153.10:1525:AZISTST"/>
        <property name="username" value="APSUSER"/>
        <property name="password" value="PASSWORDOFAPSUSER"/>
        <property name="initialSize" value="1"/>
        <property name="minIdle" value="1"/>
        <property name="maxIdle" value="1"/>
        <property name="maxActive" value="3"/>
        <property name="maxWait" value="1000"/>
        <property name="validationQuery" value="select 1 from dual"/>
        <property name="jdbcInterceptors"
                  value="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport(threshold=1500)"/>
    </bean>
</beans>

But I want to configure JNDI DataSource in Tomcat and use it.

like image 411
Tural Avatar asked Feb 12 '13 11:02

Tural


People also ask

Is JNDI used in spring?

We know that DataSource with JNDI is the preferred way to achieve connection pooling and get benefits of container implementations. Today we will look how we can configure a Spring Web Application to use JNDI connections provided by Tomcat.

What is JNDI DataSource in Tomcat?

Actual benefit of DataSource comes when we use it with a JNDI Context. For example, connection pool in a web application deployed in a servlet container. Most of the popular servlet containers provide built-in support for DataSource through Resource configuration and JNDI context.

How can I get JNDI DataSource?

To Connect to a Data SourceUse a JNDI lookup to obtain a data source reference. To obtain a reference to a data source bound to the JNDI context, look up the data source's JNDI name from the initial context object. The object retrieved in this way is cast as a DataSource type object: ds = (DataSource)ctx.


1 Answers

The reason was that, I missed factory="org.apache.tomcat.jdbc.pool.DataSourceFactory". Right definition of resource must be

  <GlobalNamingResources>
    <Resource name="jdbc/ApsuserAtAzistst"
              auth="Container"
              type="javax.sql.DataSource"
              factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
              driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@10.0.153.10:1525:AZISTST"
              username="APSUSER"
              password="PASSWORDOFAPSUSER"
              initialSize="1"
              minIdle="1"
              maxIdle="1"
              maxActive="3"
              maxWait="1000"
              validationQuery="select 1 from dual"
              jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport(threshold=1500)"
            />
  </GlobalNamingResources>
like image 114
Tural Avatar answered Sep 27 '22 16:09

Tural