Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
The moose likes Servlets and the fly likes JNDI in Servlets Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Servlets
Bookmark "JNDI in Servlets" Watch "JNDI in Servlets" New topic
Author

JNDI in Servlets

Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
Hey!
I am trying to access an MS Access Database from a Servlet using JNDI. I have configured the CATALINA_HOME/conf/server.xml and the DD web.xml file as shown below:

Server.xml file
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

<!--
JNDI WORK
-->
<Context path="/ora" docBase="ora">
<Resource name ="jdbc/publisher-access" scope="Shareable" type="javax.sql.DataSource" auth="Container" description="Publisher Access" />
<ResourceParams name="jdbc/publisher-access">

<parameter>
<name>driverClassName</name>
<value>sun.jdbc.odbc.JdbcOdbcDriver</value>
</parameter>

<parameter>
<name>url</name>
<value>jdbc dbc ublications</value>
</parameter>

</ResourceParams>
</Context>
<!--
END

-->

��.
</Host>

Following is the DD web.xml file:
<resource-ref>
<res-ref-name>jdbc/publisher-access</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>






JNDI Servlet.java code follows:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import java.sql.*;
import javax.sql.*;
import javax.naming.*;


public class JNDIServlet extends HttpServlet{
private Connection con=null;
private Statement stmt=null;
private ResultSet rs=null;

private DataSource pool;

public void init()throws ServletException{
Context env=null;
try{
env= new InitialContext();
pool=(DataSource) env.lookup("java:comp/env/jdbc/publisher-access");

if(pool==null)
throw new ServletException("unknmown data Source");
System.out.println("inside init()");
}catch(NamingException e){
System.out.println("naming error-->"+e);
}
}

public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException{

res.setContentType("text/html");
PrintWriter pw=res.getWriter();

try{

con=pool.getConnection();
stmt=con.createStatement();
rs=stmt.executeQuery("SELECT * FROM Articles");
while(rs.next()){
pw.println(rs.getString(1));
pw.println(rs.getString(2));
pw.println(rs.getString(3));
}
}catch(Exception e){
pw.println("ERROR->"+e);
}
finally{
try{
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();

}catch(SQLException e){
pw.println("Error----"+e);
}
}

}
}

When I start Tomcat and request for the servlet, I get the following error message:
ERROR->org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

Can anybody spot the error and suggest me a solution.

Regards,

Austin
Nat Dickstein
Greenhorn

Joined: Feb 26, 2005
Posts: 4
Hello Austin,

I had a similar problem last week while creating a datasource for mysql I also faced this error.

I found a solution in adding the following line in the meta-inf/context.xml-File:


For you this would mean that your context.xml-File should be looking something similar like this:



I hope this will help you.
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
Hey! Nat,
Thanks 4 the post.
But my problem remains unsolved.
I have places the context.xml file inside the META-INT folder of my ora webapp (Dir. named "ora" inside the webapp dir), but I'm still getting the same error msg.

Regards,
Austin
SCJP
Nat Dickstein
Greenhorn

Joined: Feb 26, 2005
Posts: 4
Hi Austin,

I tried to reproduce your error message and I get the following Message when I delete the RessourceLink-Line of the context.xml-File:

org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

This seems to be the same error message you get so I think the problem is somewhere inside this topic. I checked my IDE (Netbeans 4.0) to find out that the content of the META-INF/context.xml file in each web-application is copied to a xml-File in Tomcats conf-Folder (Maybe there're also differences depending on the tomcat version, I've got Tomcat5). This xml-File's name is always the web-applications name.

For you this would mean that there has to be a file ora.xml in the folder conf/Catalina/localhost/. I'm not able to say if my IDE creates this file or tomcat does. Maybe you can have try.

In your posting you wrote that you put the context.xml-File in a folder called META-INT. I guess this was just a spelling mistake because it has to be in META-INF. It would also be helpfull if you could post the source of context.xml-File.
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
Hi!,
Let me make things crystal clear here.

1.I am using Tomcat 5.
2.The name of my web application is �ora�. (CATALINA_HOME\weapps\ora)
3.Contents of CATALINA_HOME\weapps\ora\WEB-INF\web.xml (DD)

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 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"
version="2.4">

<resource-ref>
<res-ref-name>jdbc/publisher-access</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

</web-app>
4.Contents of CATALINA_HOME\weapps\ora\META-INF\context.xml file
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/ora">
<ResourceLink name="jdbc/publisher-access" global="jdbc/publisher-access" type="javax.sql.DataSource" />
</Context>

5.Contents of CATALINA_HOME\weapps\ora\WEB-INF\classes\JNDIServlet.java file


6.Contents of CATALINA_HOME\conf\server.xml file



7.http://localhost/ora/servlet/JNDIServlet
the following output is on the screen
ERROR->org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

8.On Tomcat console I am getting the �inside init()� debugging message. This means that no exception is thrown inside the init method.
9.I am using MS Access as a Database.
10.No primary key/passward.
11.I am using no IDE simple Textpad editor.

Can anybody help me!

Reagrds,
Austin

[EDIT - code tags added by Dave]
[ March 18, 2005: Message edited by: David O'Meara ]
Eugene Lucash
Ranch Hand

Joined: Feb 19, 2005
Posts: 77
You must name context xml as 'ora.xml'
and put it like this

CATALINA_HOME\conf\Catalina\localhost\ora.xml
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

"Austin MIT"-
Welcome to the JavaRanch! Please adjust your displayed name to meet the

JavaRanch Naming Policy.

You can change it

here.

Thanks! and welcome to the JavaRanch!

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Austin Hoffman
Greenhorn

Joined: Feb 20, 2005
Posts: 6
Hey!,
This is a real nightmare. I have done everything possible to configure my servlet container (Tomcat) to make use of JNDI. But, all my efforts went in vain.

Followings are the contents of my %CATALINA_HOME%\conf\Catalina\localhost\ora.xml file

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/ora">
<ResourceLink name="jdbc/publisher-access" global="jdbc/publisher-access" type="javax.sql.DataSource" />
</Context>

All other elements are unchanged.
But, still I am getting the following exception when I try to access http://localhost/ora/servlet/JNDIServlet

ERROR->org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

Anybody please help!

Regards,
Austin
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15960
    
  19

Your first mistake was in thinking that MS Access is a safe database choice for a multithreaded application. It's not. You're placing yourself at risk for severe data corruption.

However, this is the pertinent documentation.

Note that you have to define the JNDI resource name AND the resource parameters. You're not supplying a driver name to the database connection pooler.


Customer surveys are for companies who didn't pay proper attention to begin with.
Austin Hoffman
Greenhorn

Joined: Feb 20, 2005
Posts: 6
Hi,
There seems to be no end to the problem. I have even tries MySQL. I am getting the same exception.


If Tomcat documentation was that easy to understand then this discussion won�t have been exiting. Most of the tags on the HOW-To page are not known to me.




-Austin
------------------
Stas Sokolov
Ranch Hand

Joined: Apr 13, 2004
Posts: 117

A silly question. Did you put the driver in <CATALINA_HOME>/common/lib
I understood that this is obvious. But just to make sure.


Good luck for yourself.
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
Hey!
Yes buddy everything is at the right place!



This is my schedule these days
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
CAN I EXPECT ANY HELP HERE OR SUGGEST ME SOME OTHER FORUM
Sarath Mohan
Ranch Hand

Joined: Mar 17, 2001
Posts: 213
Austin,

I have done Database connection successfully thru JDBC mechanism using this help for TomCat 4.x with

http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jndi-datasource-examples-howto.html

If you are using Tomcat 5.0 go thru this

http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-resources-howto.html

Do it very slowly without missing any step

It will work

Cheers
Binu


Sarath Mohan
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
Hey!,
I would be really gr8ful if u could plz post the contents of ur server.xml and ther codes here
Regards,
Austin
Austin Hoffman
Greenhorn

Joined: Feb 20, 2005
Posts: 6
Hi!,
Can anybody post the server.xml file and the DD web.xml file for configuring JNDI on Tomcat. It has been a real nightmare trying to configure Tomcat for JNDI.


Austin
Regards,
Sarath Mohan
Ranch Hand

Joined: Mar 17, 2001
Posts: 213
I guess you don't have net connection. If you had gone thru the url I specified, you could have easily done this job. Anyway these are the main steps (Copied from Apache Site).

1. Install Your JDBC Driver

Use of the JDBC Data Sources JNDI Resource Factory requires that you make an appropriate JDBC driver available to both Tomcat internal classes and to your web application. This is most easily accomplished by installing the driver's JAR file(s) into the $CATALINA_HOME/common/lib directory, which makes the driver available both to the resource factory and to your application.


2. Declare Your Resource Requirements in Web.xml

Next, modify the web application deployment descriptor (/WEB-INF/web.xml) to declare the JNDI name under which you will look up preconfigured data source. By convention, all such names should resolve to the jdbc subcontext (relative to the standard java:comp/env naming context that is the root of all provided resource factories. A typical web.xml entry might look like this:





WARNING - Be sure you respect the element ordering that is required by the DTD for web application deployment descriptors! See the Servlet Specification for details.


3. Code Your Application's Use Of This Resource

A typical use of this resource reference might look like this:



4. Configure Tomcat's Resource Factory server.xml

YOU MUST CREATE A CONTEXT OF YOUR OWN TO USE JNDI.
To configure Tomcat's resource factory, add an elements like this to the $CATALINA_HOME/conf/server.xml file, nested inside the Context element for this web application (or nested inside a DefaultContext element for the surrounding <Host> or <Engine> element.

Hope you can create a Context for your webapplication




Note that the resource name (here, jdbc/EmployeeDB) must match the value specified in the web application deployment descriptor.

This example assumes that you are using the HypersonicSQL database JDBC driver. Customize the driverClassName and driverName parameters to match your actual database's JDBC driver and connection URL.

Cheers
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
I have followed everything as guided in the posts here and the Apache site. I am again putting everything clear here.

1.I am using Tomcat 5
2.The name of my web app is �ora� [CATALINA_HOME\webapps\ora]
3.Following is the DD web.xml file [CATALINA_HOME\webapps\ora\WEB-INF\web.xml]
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 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"
version="2.4">

<resource-ref>
<res-ref-name>jdbc/publisher-access</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>


</web-app>

4.Following is the CATALINA_HOME\conf\server.xml file

<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />

<GlobalNamingResources>

<Environment name="simpleValue" type="java.lang.Integer" value="30"/>

<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" />

</GlobalNamingResources>

<Service name="Catalina">

<Connector port="80"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />


<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />


<Connector port="8009"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />

<Engine name="Catalina" defaultHost="localhost">

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

<!--
JNDI WORK
-->
<Context path="/ora" docBase="ora">
<Resource name ="jdbc/publisher-access" scope="Shareable" type="javax.sql.DataSource" auth="Container" description="Publisher Access" />
<ResourceParams name="jdbc/publisher-access">

<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>

<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/test</value>
</parameter>

</ResourceParams>




</Context>
<!--
END

-->

</Host>

</Engine>

</Service>

</Server>
5.Following is the CATALINA_HOME\conf\Catalina\localhost\ora.xml file
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/ora">
<ResourceLink name="jdbc/publisher-access" global="jdbc/publisher-access" type="javax.sql.DataSource" />
</Context>

6.Following is the CATALINA_HOME\webapps\ora\WEB-INF\classes\JNDIServlet.java file
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import java.sql.*;
import javax.sql.*;
import javax.naming.*;


public class JNDIServlet extends HttpServlet{
private Connection con=null;
private Statement stmt=null;
private ResultSet rs=null;

private DataSource pool;

public void init()throws ServletException{
Context env=null;
try{
env= new InitialContext();
pool=(DataSource) env.lookup("java:comp/env/jdbc/publisher-access");

if(pool==null)
throw new ServletException("unknmown data Source");
System.out.println("inside init()");
}catch(NamingException e){
System.out.println("naming error-->"+e);
}
}

public void doGet(HttpServletRequest req, HttpServletResponse res)throws
ServletException, IOException{

res.setContentType("text/html");
PrintWriter pw=res.getWriter();

try{

con=pool.getConnection();
System.out.println("Connection taken frm pool");
stmt=con.createStatement();
rs=stmt.executeQuery("SELECT * FROM book");
while(rs.next()){
//pw.println(rs.getString(1));
pw.println(rs.getString(2));
pw.println(rs.getString(3));
}
}catch(Exception e){
pw.println("ERROR->"+e);
e.printStackTrace();
}
finally{
try{
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();

}catch(SQLException e){
pw.println("Error----"+e);
}
}

}
}
7.The Driver JAR file is located appropriately
CATALINA_HOMEWEB-INF\lib\ mysql-connector-java-3.0.16-ga-bin.jar
And
CATALINA_HOME\common\lib\ mysql-connector-java-3.0.16-ga-bin.jar
8.I have also tried out JDBC code from a servlet which runs successfully
(Just for demonstration purpose)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import java.sql.*;

public class JDBCServlet extends HttpServlet{
private Connection con=null;
private Statement stmt=null;
private ResultSet rs=null;

public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException{

res.setContentType("text/html");
PrintWriter pw=res.getWriter();

try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbcdbc:Publications");
stmt=con.createStatement();
rs=stmt.executeQuery("SELECT * FROM Articles");
while(rs.next()){
pw.println(rs.getString(1));
pw.println(rs.getString(2));
pw.println(rs.getString(3));
}
}catch(Exception e){
pw.println("ERROR->"+e);
}

}
}
This works fine
9.Now when I try to run the JNDIServlet (http://localhost/ora/servlet/JNDIServlet) I get the following message.

ERROR->org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

10. But on the Tomcat console �inside init()� is printed that means that the init method was successful.

Can anybody point out the problem?
Regards,
Austin
Sarath Mohan
Ranch Hand

Joined: Mar 17, 2001
Posts: 213
You have to change your context declaration as follows according to the latest server.xml Schema

<CODE>
<Context path="/ora" docBase="ora">

<Resource name="jdbc/publisher-access" auth="Container"
type="javax.sql.DataSource" username="username" password="password"
driverClassName="com.mysql.jdbc.Driver" url="mysql url"
maxActive="8" maxIdle="4"/>



</Context>
</CODE>

Ensure proper url, username and password entries in the above code

It must work.

Regards
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
I still can't get around with the prob.....the damn thing still doesn't work.....................I think I have 2 forget using JNDI...
Sarath Mohan
Ranch Hand

Joined: Mar 17, 2001
Posts: 213
Austin,

Let me know the Exception you are getting now.

Be cool

Regards
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
Nobody has posted the server.xml file.........the entire thing is struck bcz of this fuckin file....can anybody post this file with JNDI configuration...I want the entire file and not just a snippet.....
Sarath Mohan
Ranch Hand

Joined: Mar 17, 2001
Posts: 213
See this is the server.xml file. I use tomcat 5.5.7

I have context delcearation

<Context path="/rss" reloadable="true">
<Resource name="jdbc/EmployeeDB" auth="Container"
type="javax.sql.DataSource" username="root"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/sample?username=root"
maxActive="8" maxIdle="4"/>

</Context>

at the end of this server.xml


<!-- Example Server Configuration File -->
<!-- Note that component elements are nested corresponding to their
parent-child relationships with each other -->

<!-- A "Server" is a singleton element that represents the entire JVM,
which may contain one or more "Service" instances. The Server
listens for a shutdown command on the indicated port.

Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" or "Loggers" at this level.
-->

<Server port="8005" shutdown="SHUTDOWN">

<!-- Comment these entries out to disable JMX MBeans support used for the
administration web application -->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>

<!-- Global JNDI resources -->
<GlobalNamingResources>

<!-- Test entry for demonstration purposes -->
<Environment name="simpleValue" type="java.lang.Integer" value="30"/>

<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users -->
<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" />

</GlobalNamingResources>

<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" (and therefore the web applications visible
within that Container). Normally, that Container is an "Engine",
but this is not required.

Note: A "Service" is not itself a "Container", so you may not
define subcomponents such as "Valves" or "Loggers" at this level.
-->

<!-- Define the Tomcat Stand-Alone Service -->
<Service name="Catalina">

<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Each Connector passes requests on to the
associated "Container" (normally an Engine) for processing.

By default, a non-SSL HTTP/1.1 Connector is established on port 8080.
You can also enable an SSL HTTP/1.1 Connector on port 8443 by
following the instructions below and uncommenting the second Connector
entry. SSL support requires the following steps (see the SSL Config
HOWTO in the Tomcat 5 documentation bundle for more detailed
instructions):
* If your JDK version 1.3 or prior, download and install JSSE 1.0.2 or
later, and put the JAR files into "$JAVA_HOME/jre/lib/ext".
* Execute:
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA (Windows)
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA (Unix)
with a password value of "changeit" for both the certificate and
the keystore itself.

By default, DNS lookups are enabled when a web application calls
request.getRemoteHost(). This can have an adverse impact on
performance, so you can disable it by setting the
"enableLookups" attribute to "false". When DNS lookups are disabled,
request.getRemoteHost() will return the String version of the
IP address of the remote client.
-->

<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
<Connector port="8080"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
<!-- Note : To disable connection timeouts, set connectionTimeout value
to 0 -->

<!-- Note : To use gzip compression you could set the following properties :

compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml"
-->

<!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
<!--
<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />

<!-- Define a Proxied HTTP/1.1 Connector on port 8082 -->
<!-- See proxy documentation for more information about using this. -->
<!--
<Connector port="8082"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" acceptCount="100" connectionTimeout="20000"
proxyPort="80" disableUploadTimeout="true" />
-->

<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host). -->

<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">
-->

<!-- Define the top level container in our container hierarchy -->
<Engine name="Catalina" defaultHost="localhost">

<!-- The request dumper valve dumps useful debugging information about
the request headers and cookies that were received, and the response
headers and cookies that were sent, for all requests received by
this instance of Tomcat. If you care only about requests to a
particular virtual host, or a particular application, nest this
element inside the corresponding <Host> or <Context> entry instead.

For a similar mechanism that is portable to all Servlet 2.4
containers, check out the "RequestDumperFilter" Filter in the
example application (the source for this filter may be found in
"$CATALINA_HOME/webapps/examples/WEB-INF/classes/filters").

Request dumping is disabled by default. Uncomment the following
element to enable it. -->
<!--
<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
-->

<!-- Because this Realm is here, an instance will be shared globally -->

<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

<!-- Comment out the old realm but leave here for now in case we
need to go back quickly -->
<!--
<Realm className="org.apache.catalina.realm.MemoryRealm" />
-->

<!-- Replace the above Realm with one of the following to get a Realm
stored in a database and accessed via JDBC -->

<!--
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/authority"
connectionName="test" connectionPassword="test"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />
-->

<!--
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc racle:thin:@ntserver:1521 RCL"
connectionName="scott" connectionPassword="tiger"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />
-->

<!--
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="sun.jdbc.odbc.JdbcOdbcDriver"
connectionURL="jdbc dbc:CATALINA"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />
-->

<!-- Define the default virtual host
Note: XML Schema validation will not work with Xerces 2.2.
-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

<!-- Defines a cluster for this node,
By defining this element, means that every manager will be changed.
So when running a cluster, only make sure that you have webapps in there
that need to be clustered and remove the other ones.
A cluster has the following parameters:

className = the fully qualified name of the cluster class

name = a descriptive name for your cluster, can be anything

mcastAddr = the multicast address, has to be the same for all the nodes

mcastPort = the multicast port, has to be the same for all the nodes

mcastBindAddr = bind the multicast socket to a specific address

mcastTTL = the multicast TTL if you want to limit your broadcast

mcastSoTimeout = the multicast readtimeout

mcastFrequency = the number of milliseconds in between sending a "I'm alive" heartbeat

mcastDropTime = the number a milliseconds before a node is considered "dead" if no heartbeat is received

tcpThreadCount = the number of threads to handle incoming replication requests, optimal would be the same amount of threads as nodes

tcpListenAddress = the listen address (bind address) for TCP cluster request on this host,
in case of multiple ethernet cards.
auto means that address becomes
InetAddress.getLocalHost().getHostAddress()

tcpListenPort = the tcp listen port

tcpSelectorTimeout = the timeout (ms) for the Selector.select() method in case the OS
has a wakup bug in java.nio. Set to 0 for no timeout

printToScreen = true means that managers will also print to std.out

expireSessionsOnShutdown = true means that

useDirtyFlag = true means that we only replicate a session after setAttribute,removeAttribute has been called.
false means to replicate the session after each request.
false means that replication would work for the following piece of code: (only for SimpleTcpReplicationManager)
<%
HashMap map = (HashMap)session.getAttribute("map");
map.put("key","value");
%>
replicationMode = can be either 'pooled', 'synchronous' or 'asynchronous'.
* Pooled means that the replication happens using several sockets in a synchronous way. Ie, the data gets replicated, then the request return. This is the same as the 'synchronous' setting except it uses a pool of sockets, hence it is multithreaded. This is the fastest and safest configuration. To use this, also increase the nr of tcp threads that you have dealing with replication.
* Synchronous means that the thread that executes the request, is also the
thread the replicates the data to the other nodes, and will not return until all
nodes have received the information.
* Asynchronous means that there is a specific 'sender' thread for each cluster node,
so the request thread will queue the replication request into a "smart" queue,
and then return to the client.
The "smart" queue is a queue where when a session is added to the queue, and the same session
already exists in the queue from a previous request, that session will be replaced
in the queue instead of replicating two requests. This almost never happens, unless there is a
large network delay.
-->
<!--
When configuring for clustering, you also add in a valve to catch all the requests
coming in, at the end of the request, the session may or may not be replicated.
A session is replicated if and only if all the conditions are met:
1. useDirtyFlag is true or setAttribute or removeAttribute has been called AND
2. a session exists (has been created)
3. the request is not trapped by the "filter" attribute

The filter attribute is to filter out requests that could not modify the session,
hence we don't replicate the session after the end of this request.
The filter is negative, ie, anything you put in the filter, you mean to filter out,
ie, no replication will be done on requests that match one of the filters.
The filter attribute is delimited by ;, so you can't escape out ; even if you wanted to.

filter=".*\.gif;.*\.js;" means that we will not replicate the session after requests with the URI
ending with .gif and .js are intercepted.

The deployer element can be used to deploy apps cluster wide.
Currently the deployment only deploys/undeploys to working members in the cluster
so no WARs are copied upons startup of a broken node.
The deployer watches a directory (watchDir) for WAR files when watchEnabled="true"
When a new war file is added the war gets deployed to the local instance,
and then deployed to the other instances in the cluster.
When a war file is deleted from the watchDir the war is undeployed locally
and cluster wide
-->

<!--
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">

<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>

<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4001"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>

<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"
ackTimeout="15000"/>

<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>

<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
</Cluster>
-->



<!-- Normally, users must authenticate themselves to each web app
individually. Uncomment the following entry if you would like
a user to be authenticated the first time they encounter a
resource protected by a security constraint, and then have that
user identity maintained across *all* web applications contained
in this virtual host. -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->

<!-- Access log processes all requests for this virtual host. By
default, log files are created in the "logs" directory relative to
$CATALINA_HOME. If you wish, you can specify a different
directory with the "directory" attribute. Specify either a relative
(to $CATALINA_HOME) or absolute path to the desired directory.
-->
<!--
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="common" resolveHosts="false"/>
-->

<!-- Access log processes all requests for this virtual host. By
default, log files are created in the "logs" directory relative to
$CATALINA_HOME. If you wish, you can specify a different
directory with the "directory" attribute. Specify either a relative
(to $CATALINA_HOME) or absolute path to the desired directory.
This access log implementation is optimized for maximum performance,
but is hardcoded to support only the "common" and "combined" patterns.
-->
<!--
<Valve className="org.apache.catalina.valves.FastCommonAccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="common" resolveHosts="false"/>
-->
<!-- Access log processes all requests for this virtual host. By
default, log files are created in the "logs" directory relative to
$CATALINA_HOME. If you wish, you can specify a different
directory with the "directory" attribute. Specify either a relative
(to $CATALINA_HOME) or absolute path to the desired directory.
This access log implementation is optimized for maximum performance,
but is hardcoded to support only the "common" and "combined" patterns.

This valve use NIO direct Byte Buffer to asynchornously store the
log.
-->
<!--
<Valve className="org.apache.catalina.valves.ByteBufferAccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="common" resolveHosts="false"/>
-->
<Context path="/rss" reloadable="true">
<Resource name="jdbc/EmployeeDB" auth="Container"
type="javax.sql.DataSource" username="root"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/sample?username=root"
maxActive="8" maxIdle="4"/>

</Context>
</Host>

</Engine>

</Service>

</Server>




Regards
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
For the time being I am only trying to get a bean through JNDI lookup, after this works fine then I'll do connection pooling.

but even this damn thing is not working fine, its giving NullPointerException

1. CATALINA_HOME/webapps/ROOT/web.xml file
<resource-env-ref>
<description>chutiya</description>
<resource-env-ref-name>bean/pricebean</resource-env-ref-name>
<resource-env-ref-type>edu.aimk.StockPriceBean</resource-env-ref-type>
</resource-env-ref>

2. JNDIServlet
package edu.aimk;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import javax.naming.*;


public class JNDIServlet extends HttpServlet{

private StockPriceBean spbean;

public void init()throws ServletException{
Context env = null;
try{

env = (Context) new InitialContext().lookup("java:comp/env");
spbean = (StockPriceBean) env.lookup("bean/pricebean");

env.close();

if(spbean==null)
System.out.println("spbean is null");
else
System.out.println("spbean is not null");

}catch(NamingException e){
System.out.println("naming error-->"+e);
}
}

public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException{

res.setContentType("text/html");
PrintWriter pw=res.getWriter();

try{
spbean.setName("chutiya");

pw.println(spbean.getName());
}
catch(Exception e){
pw.println("ERROR here->"+e);
//e.printStackTrace();
}


}
}
3. StockPriceBean
package edu.aimk;
public class StockPriceBean{
private String name=null;

public StockPriceBean(){}

public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}

}

4 CATALINA_HOME/conf/server.xml file


<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />

<GlobalNamingResources>

<Environment name="simpleValue" type="java.lang.Integer" value="30"/>

<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" />

</GlobalNamingResources>


<Service name="Catalina">

<Connector port="80"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />


<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />


<Connector port="8009"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />

<Engine name="Catalina" defaultHost="localhost">

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">



<Resource name ="bean/pricebean" scope="Shareable" type="edu.aimk.StockPriceBean" auth="Container" description="Bean Access" />
<ResourceParams name="bean/pricebean">

<parameter>
<name>factory</name>
<value>org.apache.naming.factory.BeanFactory</value>
</parameter>

</ResourceParams>


</Host>

</Engine>

</Service>

</Server>

5.
http://localhost/servlet/edu.aimk.JNDIServlet
ERROR here->java.lang.NullPointerException

6. What is going on here
7. Can it get more complicated
Regards,
Austin
Austin Hoffman
Greenhorn

Joined: Feb 20, 2005
Posts: 6
Hey Sarath....in ur last post u poster that u poster the <context> tag after the poster contents of server.xml file....but I wanna know where exactly ...under which tag....
Sarath Mohan
Ranch Hand

Joined: Mar 17, 2001
Posts: 213
I have only declared a single context in the posted server.xml file.

that should be in side the <Host> tag. Look into the last part of the server.xml.

I haven't changed anything except this.

Still you didn't tell me which exception you got when you tried to implement connection pooling
Jeffrey Spaulding
Ranch Hand

Joined: Jan 15, 2004
Posts: 149
Austin, i feel with you.

What helped me was mentioned in


Austin,

I have done Database connection successfully thru JDBC mechanism using this help for TomCat 4.x with

http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jndi-datasource-examples-howto.html

If you are using Tomcat 5.0 go thru this

http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-resources-howto.html

Do it very slowly without missing any step

It will work

Cheers
Binu


But getting this (/&%95%$"� to work is one of the "rites-de-passage"
in this trade.

We all did it, and we all carry the scars on your forehead from
bangin-head-against-wall.

Cheer up,

J.
Austin Hoffman
Greenhorn

Joined: Feb 20, 2005
Posts: 6
Hey Sarath,
I must appreciate ur patience.

For the time being lets forget connection pooling and just try to get a
bean object through JNDI lookup. I have posted a message for the same. Plz go through it and let me know in case of any corrections/suggestions.

I won't let it go untill I get the things done!

Regards,
Austin
Austin Hoffman
Greenhorn

Joined: Feb 07, 2005
Posts: 21
Hi!,
Many things happened at my end. My comp got crahed, popped over a dozed of beer with a friend....bla...bla...bla

I won't give up....
Now I am using Tomcat 4
Want to use the ROOT context and no other context and for the time being don't want 2 get my hands dirty with connection pooling....

I guess the main problem is with setting the big fat ugly fuckin server.xml file
For the sake of readibility i have deleted all comments
1. server.xml


<Server port="8005" shutdown="SHUTDOWN" debug="0">



<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"
debug="0"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"
debug="0"/>


<GlobalNamingResources>


<Environment name="simpleValue" type="java.lang.Integer" value="30"/>

<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved">
</Resource>
<ResourceParams name="UserDatabase">
<parameter>
<name>factory</name>
<value>org.apache.catalina.users.MemoryUserDatabaseFactory</value>
</parameter>
<parameter>
<name>pathname</name>
<value>conf/tomcat-users.xml</value>
</parameter>
</ResourceParams>

</GlobalNamingResources>

<Service name="Tomcat-Standalone">


<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8080" minProcessors="5" maxProcessors="75"
enableLookups="true" redirectPort="8443"
acceptCount="10" debug="0" connectionTimeout="20000"
useURIValidationHack="false" />
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8009" minProcessors="5" maxProcessors="75"
enableLookups="true" redirectPort="8443"
acceptCount="10" debug="0" connectionTimeout="20000"
useURIValidationHack="false"
protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler"/>

<Engine name="Standalone" defaultHost="localhost" debug="0">

<Logger className="org.apache.catalina.logger.FileLogger"
prefix="catalina_log." suffix=".txt"
timestamp="true"/>

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
debug="0" resourceName="UserDatabase"/>

<Host name="localhost" debug="0" appBase="webapps"
unpackWARs="true" autoDeploy="true">


<Logger className="org.apache.catalina.logger.FileLogger"
directory="logs" prefix="localhost_log." suffix=".txt"
timestamp="true"/>

<!-- Tomcat Root Context -->

<Context path="" docBase="ROOT" debug="0">

<Resource name ="bean/pricebean" scope="Shareable" type="edu.aimk.StockPriceBean" auth="Container" description="Bean Access" />
<ResourceParams name="bean/pricebean">

<parameter>
<name>factory</name>
<value>org.apache.naming.factory.BeanFactory</value>
</parameter>

</ResourceParams>

</Context>


<!-- Tomcat Examples Context -->
<Context path="/examples" docBase="examples" debug="0"
reloadable="true" crossContext="true">
<Logger className="org.apache.catalina.logger.FileLogger"
prefix="localhost_examples_log." suffix=".txt"
timestamp="true"/>
<Ejb name="ejb/EmplRecord" type="Entity"
home="com.wombat.empl.EmployeeRecordHome"
remote="com.wombat.empl.EmployeeRecord"/>

<Environment name="maxExemptions" type="java.lang.Integer"
value="15"/>
<Parameter name="context.param.name" value="context.param.value"
override="false"/>
<Resource name="jdbc/EmployeeAppDb" auth="SERVLET"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/EmployeeAppDb">
<parameter><name>user</name><value>sa</value></parameter>
<parameter><name>password</name><value></value></parameter>
<parameter><name>driverClassName</name>
<value>org.hsql.jdbcDriver</value></parameter>
<parameter><name>driverName</name>
<value>jdbc:HypersonicSQL atabase</value></parameter>
</ResourceParams>
<Resource name="mail/Session" auth="Container"
type="javax.mail.Session"/>
<ResourceParams name="mail/Session">
<parameter>
<name>mail.smtp.host</name>
<value>localhost</value>
</parameter>
</ResourceParams>
<ResourceLink name="linkToGlobalResource"
global="simpleValue"
type="java.lang.Integer"/>
</Context>

</Host>

</Engine>

</Service>

</Server>

2. web.xml in ROOT web app
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<display-name>Welcome to Tomcat</display-name>
<description>
Welcome to Tomcat
</description>

<resource-env-ref>
<description>something very ugly</description>
<resource-env-ref-name>bean/pricebean</resource-env-ref-name>
<resource-env-ref-type>edu.aimk.StockPriceBean</resource-env-ref-type>
</resource-env-ref>

</web-app>

3. Code
package edu.aimk;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import javax.naming.*;


public class JNDIServlet extends HttpServlet{

private StockPriceBean spbean;

public void init()throws ServletException{
Context env = null;
try{

env = (Context) new InitialContext().lookup("java:comp/env");
spbean = (StockPriceBean) env.lookup("bean/pricebean");

env.close();

if(spbean==null)
System.out.println("spbean is null");
else
System.out.println("spbean is not null");

}catch(NamingException e){
System.out.println("naming error-->"+e);
}
}

public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException{

res.setContentType("text/html");
PrintWriter pw=res.getWriter();

try{
spbean.setName("PricePP");

pw.println(spbean.getName());
}
catch(Exception e){
pw.println("ERROR here->"+e);
//e.printStackTrace();
}


}
}
4 . package edu.aimk;
public class StockPriceBean{
private String name=null;

public StockPriceBean(){}

public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}

}
5. http://localhost:8080/servlet/edu.aimk.JNDIServlet
ERROR here->java.lang.NullPointerException

I wanna smash my comp
Sarath Mohan
Ranch Hand

Joined: Mar 17, 2001
Posts: 213
Austin,

I don't see anything wrong in your code. Of course, we know that while executing the doGet method (I mean when a request comes) bean object is null.
We need to find out why this happenend?
Check the Context object is created correctly?

Are you sure that bean is creared successfully in init() method?

Try to set and get there itself and see the tomcat server logs.

I am sorry i could not test it on my server since it is not Tomcat 4.x
Paul Bartels
Greenhorn

Joined: Jun 16, 2008
Posts: 11

Hi Austin, I completely sympathize with your connection pooling woes.

I just wanted to check if you had set up Tomcat connection pooling with success in other apps and perhaps the problem is just with Access.

For example, have you tried the Tomcat connection pooling example here that sets up a simple connection pool example with 1 jsp, a web.xml, the tags to put in your context and a very simple MySQL database.

If you can get that going, then you could try to alter your datasource to Access (if that's what you must use) and see if it works with the simple example provided.

If it works, then you can more easily build your app around the working connection pool.
If it doesn't, you can at least you can narrow down your problem.

I took about two days to get the simple example going! I had a dodgy Tomcat install.
Missing files - tears were shed...
good luck!

I'll be keeping an eye on this thread b/c some of your code looks similar to what I'm doing.
I find the whole context.xml/server.xml/[myapp].xml/META-INF vs WEB-INF VERY confusing to say the least!


SCJP5 SCWCD
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JNDI in Servlets
 
Similar Threads
JBOSS connection pooling
datasource???
JNDI null issue
making connection pool in Glassfish v3
Tomcat4.1 ConnectionPool ( javax.naming.NameNot Found Exception: Name java: