• Post Reply Bookmark Topic Watch Topic
  • New Topic

Problem with database connection and tomcat

 
Casandra justina
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please help! I am trying to make a simple login using netbeans, derby database included in netbeans and tomcat server.

I made everything nice and separated: I have a model package with a class called DbConnector that has the following method:


Then i have another class, an userDAODB that has a password check method:


in the main method of this class i tested everything, it works very nice, logs me in, other methods work too, no problem what so ever.

But then i go to my servlet:


So when i start the webpage and i try to click on the login button I get a NullPointerException
com.model.UserDAODB.checkPassword(UserDAODB.java:14) - so line 2 here

I figured out why (because i get a null connection), what i don't know is how to fix it. It works perfect without the server.
I have been googling a bit, i placed the derby.jar and the derbyclient.jar in the lib directory of tomcat, i tried to modify the context.xml of my application, but then it wouldn't even start anymore.

Could you please help me and tell me how to fix it in beginners language?

*note: I translated the class names and variable names to post here, but i might have missed some, so if you see them it is just translation error.
 
Casandra justina
Greenhorn
Posts: 11
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I fixed it (i used the information i found here: http://stackoverflow.com/questions/11428964/connecting-to-derby-database-with-tomcat-as-the-server)

I wrote this in my context.xml (of my application)



And added this to my web.xml


And also in my DbConnector:



And now it works

I hope it is ok to answer my own question, hoping it might help someone someday...
 
Stefan Evans
Bartender
Posts: 1822
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just to clarify things here did you also change your call to DriverManager.getConnection() to a JNDI lookup?

The changes you have made (in your previous post)
- Define a JNDI Datasource (changes to context.xml and web.xml)
- Load a database driver to use with DriverManager

I don't think all of those changes are needed.

There are two standard ways to get a database connection
- Make one from scratch with DriverManager class.
- get one from a JNDI Datasource

The second one is preferable as you can then utilise database connection pooling features of the Datasource.

In your code you were originally using Driver manager.
Presumably the database connection was null, because it was throwing a SQLException to do with not finding a suitable driver. (and returning null from your code as a result)
You fixed that bug by loading the driver
I look on that catch exception and return null as a bit of a code smell. You are hiding the actual error. At the least you should log it. More likely you should let the exception through, as it is just going to create a NiullPointerExceptoin when someone assumes the Connection is valid.


The JNDI configuration you have put in is not being used. So I think changes to context.xml and web.xml are actually irrelevant to it working right now (try changing them back and see)

Personally I think you should keep the JNDI configuration and change your getConnection method to look up the Datasource from JNDI and get it that way.

 
Casandra justina
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you! I have deleted the changes I made to context.xml and web.xml and indeed it still works, so the only thing that mattered was, like you said, putting the Class.forName("org.apache.derby.jdbc.ClientDriver");

Now I've put them back and I am trying to use the JNDI Datasource. I placed this code directly in my Servlet, cause I hoped it would be easier for me, till I get everything working:


(I found the code here: http://www.javapractices.com/topic/TopicAction.do?Id=127 )

And i get this:





 
J. Kevin Robbins
Bartender
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It looks like a problem with your JNDI setup. I'm a little out of my comfort zone here because once JNDI is setup and working it can be years before you look at it again, so I admit I'm rusty. But mine isn't setup in context.xml, it's in server.xml. It looks like this:


And btw, responding to your own question when you find a solution is not only okay, it's encouraged and appreciated. It's likely to help someone else who has the same problem somewhere in the future.

I also removed the username and password from your post.

 
Stefan Evans
Bartender
Posts: 1822
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Putting the JNDI setup in a specific application's context.xml file is preferable to having it in server.xml if it is just being used by that application.

If it can't find the JDBC driver, then you have to put the jar file in a place where the Tomcat server can get at it.
I presume you have it in your application's WEB-INF/lib directory.
Because JNDI datasources are controlled by the container, it needs to be in the classpath for the container, not just for your application.
Try copying it to the TOMCAT_HOME/lib directory, restarting and see if it improves matters. At the very least it should change the error message :-)

 
Tim Holloway
Bartender
Posts: 18412
58
Android Eclipse IDE Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Normally, I'd move this thread to the Tomcat forum where the Tomcat experts hang out. But most of it is about J(2)EE databases in general, so I'm leaving it in the Servlets forum, except for one minor Tomcat-related note.

What you are actually defining when you use the Resource xml element is a database connection pool (more on this shortly). You can define a shared pool (used by multiple webapps) in the server.xml file or you can define a single-app pool in the Context element, which should be a stand-alone file. You can define Contexts in the server.xml file itself, but that is a very bad practice and the Tomcat developers urge you not to.

Database connection pools are generally recommended over fixed database connection allocations in webapps because there's a lot of overhead involved in creating connections and if you have a lot of users making a lot of database requests, it's far more efficient to keep a pool of pre-created Connections than to create one every time you need one. And don't even think about stuffing a Connection in a session-scope object - that's an invitation to tragedy.

Connection pools belong to the server. so the classes needed to construct the pool and its contents must be in the server's classpath. Which in Tomcat version 6 and later means put the jdbc driver jar(s) in the TOMCAT_HOME/lib directory, NOT in the application WAR (WEB-INF/lib).

Incidentally, in addition to the better performance, there's another reason to use server Connection Pools. The database credentials, vendor, and location (url) are defined in the pool, not in the webapp. So it's easy to change them - you don't have to change the webapp like you would if the app did "brute force" Connection construction. That's one of the ways I eliminate headaches in testing and support. Since that info is all external, it helps me to construct a single WAR that can be used in both test and production environments even though the deployed WAR would be accessing different databases for test than for production. It also means that I don't need to know production database passwords to create a production WAR.
 
J. Kevin Robbins
Bartender
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Holloway wrote:You can define a shared pool (used by multiple webapps) in the server.xml file or you can define a single-app pool in the Context element, which should be a stand-alone file. You can define Contexts in the server.xml file itself, but that is a very bad practice and the Tomcat developers urge you not to.

This is good information that I didn't know. It explains why our setup was done in server.xml; our apps all access the same AS400. I didn't realize it could be done in context.xml.
 
Tim Holloway
Bartender
Posts: 18412
58
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
J. Kevin Robbins wrote:
Tim Holloway wrote:You can define a shared pool (used by multiple webapps) in the server.xml file or you can define a single-app pool in the Context element, which should be a stand-alone file. You can define Contexts in the server.xml file itself, but that is a very bad practice and the Tomcat developers urge you not to.

This is good information that I didn't know. It explains why our setup was done in server.xml; our apps all access the same AS400. I didn't realize it could be done in context.xml.


You can define the Context (technical name: server-dependent deployment descriptor, as opposed to the server-indepenent deployment descriptor in WEB-INF/web.xml) in a number of places.

1. As a META-INF/context.xml file in the WAR

2. As an "xxxxx.xml" file in the engine's context directory (default name: TOMCAT_HOME/conf/Catalina/localhost)

3. As an element in TOMCAT_HOME/conf/server.xml

Option #3 was the original way, but it's bad because server.xml only gets processed on Tomcat startup. So if you change the context definition, you have to restart the entire Tomcat server and all webapps running under it.

Option #2 is the preferable way. If you replace that file with a new copy, Tomcat will detect the change and redeploy the corresponding webapp on the fly.

Option #1 is OK for defaults, but if you want to customize the deployment info (say to point to a test or production database), then option #2 is better.

There are precedence rules (as well as additional rules not mentioned here) that determine what happens if you have a Context in more than one place. It's all explained in the official Tomcat docs.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!