Failed to look up JNDI DataSource In Spring Boot Application - spring

I have done the bellow mentioned configuration for JNDI DataSource connection for Spring Boot Application that uses an external tomcat.
Tomcat's server.xml configuration like
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="jdbc/MyPostgresDB"
global="jdbc/MyPostgresDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/postgres"
username="postgres"
password="postgres"
maxActive="100"
maxIdle="20"
minIdle="5"
maxWait="10000"/>
Context.xml like
<Context>
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<ResourceLink name="jdbc/MyPostgresDB"
global="jdbc/MyPostgresDB”
auth="Container"
type="javax.sql.DataSource" />
Defined the application.properties for spring boot in right way like
spring.datasource.jndi-name=java:comp/env/jdbc/MyPostgres
Updated the web.xml like
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<resource-ref>
<description>JNDI LookUp</description>
<res-ref-name>jdbc/MyPostgresDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<!-- <res-sharing-scope>Shareable</res-sharing-scope> -->
</resource-ref>
</web-app>
Still getting the exception like
org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException:
Failed to look up JNDI DataSource with name
'java:comp/env/jdbc/MyPostgres'
(Full Stacktrace not given as every where it is given)
So what is the solution or why I am getting this exception.
Don't come with the idea of embedded tomcat server for spring boot.
Please help me.

Should be
spring.datasource.jndi-name=java:comp/env/jdbc/MyPostgresDB
from what you wrote above in your definitions.

we should add factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" in Resource tag of server.xml and make sure to set JndiDatasource in the class where you extends SpringBootServletInitializer class
For elaborate answer please refer here

Related

Configuring the jmsConnectionFactory in server.xml for solace resource adapter doesn't work

I am trying to integrate solace with web sphere liberty 20 version using ejb2 and solace Resource adapter. I have configured MDB bean in ejb which listens to a queue. I am able to get the messages on the MDB, but while processing I need to publish the response back to a queue and this queue name is dynamic based on the messages from the upstream system. So I can not configured publisher as stateless bean in container.
Now I want to use the connection factory in publisher code which is configured in server.xml for MDB using solace resource adapter.
I have tried the following way.
in server.xml:
<featureManager>
<feature>javaee-8.0</feature>
<feature>localConnector-1.0</feature>
<feature>jndi-1.0</feature>
<feature>wasJmsClient-2.0</feature>
<feature>wasJmsServer-1.0</feature>
<feature>wasJmsSecurity-1.0</feature>
<feature>mdb-3.2</feature>
<feature>servlet-4.0</feature>
<feature>ejb-3.2</feature>
<feature>ejbHome-3.2</feature>
<feature>adminCenter-1.0</feature>
<feature>jca-1.7</feature>
<feature>jms-2.0</feature>
<feature>webProfile-8.0</feature>
<resourceAdapter autoStart="true" id="solace" location="sol-jms-ra-10.10.0.rar">
<properties.solace ConnectionURL="URL" UserName="user1" Password="pwd" MessageVPN="TEST_VPN"/>
</resourceAdapter>
<jmsActivationSpec id="JNDI/LISTENER">
<properties.solace connectionFactoryJndiName="myCF" destination="queue" destinationType="javax.jms.Queue" />
</jmsActivationSpec >
<jmsConnectionFactory id="JNDI/J2C/CF" jndiName="JNDI/J2C/CF">
<properties.solace ConnectionFactoryJndiName="myCF"/>
</jmsConnectionFactory>
and In my publisher code, doing jndi lookup as below.
Context ctx = new InitialContext();
connectionFactory = (QueueConnectionFactory) ctx.lookup("java:comp/env/JNDI/J2C/CF");
connection = connectionFactory.createQueueConnection();
but getting the below exception
javax.naming.NameNotFoundException: javax.naming.NameNotFoundException: java:comp/env/JNDI/J2C/CF
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:355)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:370)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:149)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
can someone please help me here.
You need to define a binding from resource reference name java:comp/env/JNDI/J2C/CF to the configured jndiName, JNDI/J2C/CF.
One standard way to do that is with an #Resource annotation in your web or ejb component that wants to look it up (you could also use the value injected by the #Resource annotation instead of the lookup). For example,
#Resource(name = "java:comp/env/JNDI/J2C/CF", lookup = "JNDI/J2C/CF")
QueueConnectionFactory qcf;
Another approach that you can use instead to define the resource reference is to do so within your ejb-jar.xml file. For example,
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
version="2.1">
<enterprise-beans>
<message-driven>
<ejb-name>MyMessageDrivenBean</ejb-name>
<ejb-class>org.example.MyMessageDrivenBean</ejb-class>
<messaging-type>javax.jms.MessageListener</messaging-type>
<transaction-type>Bean</transaction-type>
<resource-ref>
<res-ref-name>java:comp/env/JNDI/J2C/CF</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
<lookup-name>JNDI/J2C/CF</lookup-name>
</resource-ref>
</message-driven>
</enterprise-beans>
</ejb-jar>
or
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
version="2.1">
<enterprise-beans>
<session>
<ejb-name>MyStatelessBean</ejb-name>
<ejb-class>org.example.MyStatelessBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<resource-ref>
<res-ref-name>java:comp/env/JNDI/J2C/CF</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
<lookup-name>JNDI/J2C/CF</lookup-name>
</resource-ref>
</session>
</enterprise-beans>
</ejb-jar>
Also, given that you want a QueueConnectionFactory, you need to be using the jmsQueueConnectionFactory configuration element,
<jmsQueueConnectionFactory id="JNDI/J2C/CF" jndiName="JNDI/J2C/CF">
<properties.solace ConnectionFactoryJndiName="myCF"/>
</jmsQueueConnectionFactory>

Jetty JNDI configuration vs Spring lookup

I have got a problem with JNDI configuration on Jetty server. I cannot by any means configure it in a way that afterwards Spring (3.0.5) can retrieve JNDI variables.
I have some credentials which I do not want to store in properties so that it will not exist in git repo. My web application is running on Jetty (most recent version 9.2.3), thus I came up with idea to store this credentials in Jetty web application context. Jetty provides such solution with jetty-env.xml. So I have created jetty-env.xml file in my WEB-INF/ like following:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="webappCtx" class="org.eclipse.jetty.webapp.WebAppContext">
<New id="username" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="webappCtx"/></Arg> <!-- scope -->
<Arg>server/username</Arg> <!-- name -->
<Arg type="java.lang.String">myUsername</Arg> <!-- value -->
</New>
<New id="password" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="webappCtx"/></Arg> <!-- scope -->
<Arg>server/password</Arg> <!-- name -->
<Arg type="java.lang.String">qwerty</Arg> <!-- value -->
</New>
</Configure>
After that I have defined binding in the web.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="MyWebApp" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>My Web App</display-name>
<!-- INITIALIZE SPRING -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- JETTY-ENV JNDI -->
<resource-ref>
<res-ref-name>server/username</res-ref-name>
<res-type>java.lang.String</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>server/password</res-ref-name>
<res-type>java.lang.String</res-type>
</resource-ref>
</web-app>
And configured my Spring context in this way:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<jee:jndi-lookup id="serverUsername" jndi-name="server/username" expected-type="java.lang.String" resource-ref="true" />
<jee:jndi-lookup id="serverPassword" jndi-name="server/password" expected-type="java.lang.String" resource-ref="true"/>
<bean name="abstractServerConnectionFactory" class="my.package.ServerConnectionFactory" abstract="true">
<constructor-arg value="${server.host}"/>
<constructor-arg value="${server.port}"/>
<constructor-arg ref="serverUsername"/>
<constructor-arg ref="serverPassword"/>
</bean>
</beans>
After that I am starting Jetty with --add-to-startd=jndi enabled and I am always getting javax.naming.NameNotFoundException when creating serverUsername and serverPassword. I have tried many modfication, but non have seem to work. I have tried:
Changing org.eclipse.jetty.plus.jndi.Resource to org.eclipse.jetty.plus.jndi.EnvEntry and then refering to it via resource-env-ref in web.xml
Setting resource scope to JVM instead of webapp so changing <Arg><Ref refid="webappCtx"/></Arg> to <Arg></Arg> as mentioned here
Adding automatic binding without using web.xml as mentioned here
<Call name="bindToENC">
<Arg>server/username</Arg> <!-- binds server/username to java:comp/env/server/username for this webapp -->
</Call>
And many other, but it just does not work. Please give me a working example how I can get it to work. Thank you!
Ok so I have managed to get this working. The problem was the configuration. I am using Jetty 9 so according to the official documentation (http://www.eclipse.org/jetty/documentation/current/jndi.html#jndi-quick-setup) the only thing that needs to be done prior to using JNDI in Jetty is adding jndi module to start.d by doing --add-to-startd=jndi. And well, that's not exactly true, because this will enable JNDI, BUT WILL NOT INCLUDE jetty-env.xml contents (Jetty do not even touch it). I've been reading about the container lifecycle and noticed that in order to use JNDI one need to include following classes in the web application context configuration classes set:
org.eclipse.jetty.plus.webapp.EnvConfiguration
org.eclipse.jetty.plus.webapp.PlusConfiguration
This is done by default in $JETTY_HOME/etc/jetty-plus.xml, which is config file for plus module. So in order to add this classes into the Jetty container lifecycle, and by this include and parse jetty-env.xml, one need to enable plus module in addition to jndi module (jndi does not depend upon plus)! Thus I have changed my start.d config by invoking --add-to-startd=jndi,plus (no space between modules) and everything started working like a charm.

Webpshere server is not gettin started after adding MDB configuration to ejb-jar xml

I have added MDB configuration to the ejb-jar.xml and ibm-ejb-jar-bnd.xmi files and then restart fails with throwing the below error,if i revert my changes it started working fine.
Error Message: Caused by: java.lang.IllegalStateException: Parent Translator (EnterpriseBeansTranslator(entity|session|message-driven,841888302)) did not find a Child Translator for "message-driven-destination".
Could you please help me to understand the root cause of the issue. Below is the MDB configuration added.Please help me if the issue is due to xsd??
<ejb-jar id="ejb-jar_1" version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
<enterprise-beans>
<message-driven id="MessageDriven_TestJMSMDBL">
<description>Message Driven Bean for JMS Listener TestJMSMDBL</description>
<ejb-name>TestJMSMDBL</ejb-name>
<ejb-class>com.pega.pegarules.internal.etier.mdb.PRJMSListenerBoot</ejb-class>
<transaction-type>Container</transaction-type>
<message-driven-destination id="MessageDrivenDestination_TestJMSMDBL">
<destination-type>javax.jms.Queue</destination-type>
</message-driven-destination>
<env-entry>
<env-entry-name>PRListener</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>TestJMSMDBL</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>UseCMT</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>true</env-entry-value>
</env-entry>
<ejb-local-ref id="EJBLocalRef_TestJMSMDBL_EngineBMTLocal">
<description/>
<ejb-ref-name>ejb/EngineBMTLocal</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home>com.pega.pegarules.internal.etier.interfaces.EngineLocalHome</local-home>
<local>com.pega.pegarules.internal.etier.interfaces.EngineLocal</local>
<ejb-link>EngineBMT</ejb-link>
</ejb-local-ref>
<ejb-local-ref id="EJBLocalRef_TestJMSMDBL_EngineCMTLocal">
<description/>
<ejb-ref-name>ejb/EngineCMTLocal</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home>com.pega.pegarules.internal.etier.interfaces.EngineLocalHome</local-home>
<local>com.pega.pegarules.internal.etier.interfaces.EngineLocal</local>
<ejb-link>EngineCMT</ejb-link>
</ejb-local-ref>
</message-driven>
</enterprise-beans>
Your MDB definition is not correct. You should have something like below. It should be <message-destination-type> not <message-driven-destination>.
<message-driven id="MyMDB">
<ejb-name>MyMDB</ejb-name>
<ejb-class>ejbs.MyMDBBean</ejb-class>
<messaging-type>javax.jms.MessageListener</messaging-type>
<transaction-type>Container</transaction-type>
<message-destination-type>javax.jms.Queue</message-destination-type>
</message-driven>
Here is the sample binding file. But you can remove binding for message driven from file and then install it using console. You will be able to define mapping there. Afterwards you can export application from the console and you may then extract correct binding file from there.
<?xml version="1.0" encoding="UTF-8"?>
<ejbbnd:EJBJarBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ejb="ejb.xmi" xmlns:ejbbnd="ejbbnd.xmi" xmi:id="EJBJarBinding_1409479703640">
<ejbJar href="META-INF/ejb-jar.xml#ejb-jar_ID"/>
<ejbBindings xmi:type="ejbbnd:MessageDrivenBeanBinding" xmi:id="MessageDrivenBeanBinding_1409479703640" activationSpecJndiName="myActiveSpec" destinationJndiName="eis/as1">
<enterpriseBean xmi:type="ejb:MessageDriven" href="META-INF/ejb-jar.xml#MyMDB"/>
</ejbBindings>
</ejbbnd:EJBJarBinding>

Configure DBCP inside of Tomcat

I am trying to inject DataSource into Servlet. Finally I've annotated datasource field with #Resource and some DBCP's BasicDataSource was injected there. But it has no configuration. No db url, no driver class, nothing. Naturally I got NullPointerException when trying to getConnection(). What am I doing wrong?
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>ua.test.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/serve</url-pattern>
</servlet-mapping>
<resource-ref>
<res-ref-name>jdbc/MyDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<injection-target>
<injection-target-class>ua.test.TestServlet</injection-target-class>
<injection-target-name>dataSource</injection-target-name>
</injection-target>
</resource-ref>
</web-app>
context.xml
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="30" maxWait="10000"
username="tomcat" password="tomcat" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"/>
</Context>
Obviously no one gave a sh*t about my sorrow. So I will answer myself.
Tomcat has it's own(probably modified) copy of Apache Commons DBCP under package org.apache.tomcat.jdbc, but also for some stupid reason includes original DBCP under org.apache.commons.dbcp package. What happens when I try to inject Datasource with #Resource annotation is Tomcat instanting Datasource from original package and injecting this instance to my field. To make Tomcat to use his own copy of DBCP I had to modify my context.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/MyDB"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="30" maxWait="10000"
username="tomcat" password="tomcat"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"/>
</Context>
Basicaly I just added this line:
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
Thanks to everyone who knew the reason but ignored this question for so long time :-)

JNDI spring embedded tomcat : maven multi module project

I still cant get this thing in my head :
this is how my project looks :
--app
--app-core (spring)
--app-model (pojo)
--app-service (jersey) >> final package as war (dependencies (appcore+appmodel))
Now here where should my applicationContext.xml sits ????
Dependencies of Spring goes to only app-core ???? ...
UPDATE
app-core (spring) has applicationContext.xml, Know I would like to use JNDI with embedded tomcat (tomcat-maven-plugin).
Have created context.xml inside webapp/META-INF it looks like :-
<?xml version='1.0' encoding='utf-8'?>
<Context docBase="nweb" path="/nweb" reloadable="true">
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Resource name="jdbc/TestDS" auth="Container"
type="javax.sql.DataSource"
driverClass="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:sqlserver://localhost:1433;DatabaseName=TestData"
username="sa" password=""/>
</Context>
..
my applicationContext.xml : -
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/TestDS"></property>
</bean>
</beans>
with the above I get this below error :
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: javax.naming.NameNotFoundException: Name TestDSis not bound in this
Context
at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:152)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
at
Any suggestions if am missing out anything ?
Typically you would configure a ContextLoaderListener on your web.xml for your root application context:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
This class uses the param value contextConfigLocation -- from which you can explicitly specify where your applicationContext.xml should be:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
try
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<contextFile>webapp/META-INF/context.xml</contextFile>
</configuration>
</plugin>
try <property name="jndiName" value="java:comp/env/TestDS"></property>
if you are using embedded tomcat 7 then you should call
tomcat.enableNaming();
You have an application working with JNDI here. I have been using JNDI on a PaaS where they explain how to do the binding between your app and the db. You can have more details on this tutorial.
Basically you need to put this on your datasource.xml file:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/mydb" resource-ref="true"
expected-type="javax.sql.DataSource"/>
Then, on your Tomcat server, you have several possibilities as you can see on the Spring tutorial I put the link. Easiest way is going to $CATALINA_HOME/conf/context.xml and put something like this.
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" maxActive="20" maxIdle="10" minIdle="1" name="jdbc/mydb" password="dbUserPassword" testOnBorrow="true" testWhileIdle="true" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/dbName" username="dbUserName" validationInterval="5000" validationQuery="select 1"/>

Resources