Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[JDBC] jdbc works in java app, fails in servlet: "no suitable jdbc found"

9 views
Skip to first unread message

phil...@aol.com

unread,
Jun 2, 2010, 12:56:22 AM6/2/10
to
Hi - I am new to Postgresql (and Eclipse and Tomcat--triple threat),and
would have posted this question in the general section, but thought it
might be more appropriate here since it concerns the JDCB.

I have successfully installed and run some example programs from Core
Java II by Horstmann. I wish to connect to a database from a Java
Servlet, and tried using the same code and properties as is being used
in a Java application program (which successfully connects to the same
db), but am getting the following error when executing the
DriverManager.getConnection(url, username, password) code:

java.sql.SQLException: No suitable driver found for
jdbc:postgresql:gpsdata

Is a different driver needed in the "Servlet" context? I've done
everything I can think of to make the Java Application which works and
the Java Servlet which fails as similar as possible, down to hardcoding
them both to the same "database.properties" text file. This file
contains the following data:

jdbc.url=jdbc:postgresql:gpsdata
jdbc.password=********
jdbc.username=postgres
jdbc.drivers=org.postgresql.Driver

If I understand correctly, the third parameter of the URL defaults to
//localhost:5432/gpsdata, which I can confirm is the location given by
inspection in pgAdmin III. I've tried writing out the full url, and
gone so far as to make sure everything is lowercase. But as I said, the
same connection that will work in a Java application will not work in
the servlet context.

In researching your archives, I came across another individual with the
"no suitable driver" problem. His closing comments included this:

>>The problem had nothing to do with it being a web application
(because you don't have to deploy it to generate a database schema) but
you did put me onto the right train of thought. The problem was that
although I had added the postgresql jdbc driver to my maven project as
a dependency, I hadn't added it as a dependency for the
hibernate3-maven-plugin.<<

But I'm not sure how I can apply that (I'm not using Maven, etc.),
except to ask if there are dependancies I am overlooking? Is there,
perhaps, something in the configuration of Apache that might be
omitted? Something I'm supposed to put in the web.xml file? In both the
application and the servlet, the jdbc is connected as a library, via
Eclipse's "Data Management/Connectivity/Driver Definitions" section of
the preferences. And if one right-click's and selects the properties of
the connected library in each project, the library is designated as a
"Connectivity Driver Definition".

jdbc I am using: postgresql-8.4-701.jdbc4.jar

Many thanks in advance for any assistance!

--
Sent via pgsql-jdbc mailing list (pgsql...@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-jdbc

Craig Ringer

unread,
Jun 2, 2010, 2:02:49 AM6/2/10
to
On 02/06/10 12:56, phil...@aol.com wrote:
> Hi - I am new to Postgresql (and Eclipse and Tomcat--triple threat),and
> would have posted this question in the general section, but thought it
> might be more appropriate here since it concerns the JDCB.
>
> I have successfully installed and run some example programs from Core
> Java II by Horstmann. I wish to connect to a database from a Java
> Servlet, and tried using the same code and properties as is being used
> in a Java application program (which successfully connects to the same
> db), but am getting the following error when executing the
> DriverManager.getConnection(url, username, password) code:
>
> java.sql.SQLException: No suitable driver found for jdbc:postgresql:gpsdata

The JRE's JDBC is complaining that it doesn't know what to do with URLs
of type 'jdbc:postgresql'. This means that the PostgreSQL JDBC driver
hasn't been loaded.

You need to preload the PostgreSQL driver, org.postgresql.Driver , to
register it with JDBC so that JDBC knows to use it for 'postgresql' URLs.

Load the JDBC driver with with 'Class.forName' if it's on the System
classpath, or (preferably) the classloader that loaded your servelet.

> Is a different driver needed in the "Servlet" context?

No, but you might need to load it differently if your container doesn't
use the system classloader.

You can use the classloader that loaded the currently running object with:

this.getClass().getClassLoader().loadClass('org.postgresql.Driver');

--
Craig Ringer

Tech-related writing: http://soapyfrogs.blogspot.com/

Lew

unread,
Jun 2, 2010, 6:58:55 PM6/2/10
to
phil...@aol.com wrote:
>> Hi - I am new to Postgresql (and Eclipse and Tomcat--triple threat),and
>> would have posted this question in the general section, but thought it
>> might be more appropriate here since it concerns the JDCB.
>>
>> I have successfully installed and run some example programs from Core
>> Java II by Horstmann. I wish to connect to a database from a Java
>> Servlet, and tried using the same code and properties as is being used
>> in a Java application program (which successfully connects to the same
>> db), but am getting the following error when executing the
>> DriverManager.getConnection(url, username, password) code:
>>
>> java.sql.SQLException: No suitable driver found for jdbc:postgresql:gpsdata

Craig Ringer wrote:
> The JRE's JDBC is complaining that it doesn't know what to do with URLs
> of type 'jdbc:postgresql'. This means that the PostgreSQL JDBC driver
> hasn't been loaded.
>
> You need to preload the PostgreSQL driver, org.postgresql.Driver , to
> register it with JDBC so that JDBC knows to use it for 'postgresql' URLs.
>
> Load the JDBC driver with with 'Class.forName' if it's on the System
> classpath, or (preferably) the classloader that loaded your servelet.

Better yet, do it Tomcat's way, configuring a 'DataSource' in the context.

phil...@aol.com wrote:
>> Is a different driver needed in the "Servlet" context?

Craig Ringer wrote:
> No, but you might need to load it differently if your container doesn't
> use the system classloader.

He said he was using Tomcat. Tomcat's classloader use is very well documented.
<http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html>

> You can use the classloader that loaded the currently running object with:
>
> this.getClass().getClassLoader().loadClass('org.postgresql.Driver');

The driver should be loaded in a static context, not an instance context.
Furthermore, that code as shown will not compile. Further furthermore, I see
nothing in the documentation for 'ClassLoader#loadClass()' that promises to
initialize the class, unlike 'Class.forName()'. If the class is not
initialized, the driver won't register with the 'DriverManager'. I think
you're selling a pig in a poke here.

Much better, follow the directions at:
<http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html>
and
<http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html>

I've used this technique a lot and it works beautifully. For one thing, it's
a wonder to have the connection parameters externalized to a deployment
descriptor when you're moving the application around from development server
to test server to production to different development server.

Go with the Tomcat way and forget the kludgey direct uses of Java reflection.

--
Lew

Craig Ringer

unread,
Jun 2, 2010, 10:19:33 PM6/2/10
to
On 3/06/2010 8:28 AM, phil...@aol.com wrote:
> Thank you for the reply!
>
>> You need to preload the PostgreSQL driver...
>
> Being new to this, I find myself second-guessing words as simple as
> "preload". The servlet "NearbyTest" has a constructor and a single
> method "doGet" which is invoked by an HTML page. As the first working
> statement in the "doGet" method (at this point everything else is
> commented out), I tried using the recommended statements. Both of them
> elicited the same error message:
>
> try {
> // Class.forName("org.postgresql.Driver");
> this.getClass().getClassLoader().loadClass("org.postgresql.Driver");
> } catch (ClassNotFoundException e1) {
> e1.printStackTrace();
> }
>
> java.lang.ClassNotFoundException: org.postgresql.Driver

I'd say your classpath is misconfigured; the classloader cannot find
PostgreSQL.

On web service containers sometimes the dependencies for the servelet
must all be embedded in a .war with the serverlet jar. Is that the case
here?

> Is there another stage (prior to the servlet's
> "doGet") at which the "preloading" should occur?

Nope, just loading the class is sufficient.

> The stack trace indicates code that is part of Apache. Is there possibly
> something that has to be configured in Apache that is missing?

Well the trace refers to org.apache.catalina.loader.WebappClassLoader ,
which is a part of Apache Catalina. It has nothing to do with the Apache
web server except that they're both from the Apache project.

Catalina is Tomcat's servlet container.

That further suggests that you need to configure your classpath in your
web app environment, or have an issue with how your app and dependencies
are packaged. I've only done this stuff with Maven & Netbeans targeting
Glassfish, so I can't really offer much help with the details of doing
it right using Eclipse's build system and a Tomcat target.

--
Craig Ringer

phil...@aol.com

unread,
Jun 2, 2010, 8:28:13 PM6/2/10
to
Thank you for the reply!

>You need to preload the PostgreSQL driver...

Being new to this, I find myself second-guessing words as simple as
"preload". The servlet "NearbyTest" has a constructor and a single
method "doGet" which is invoked by an HTML page. As the first working
statement in the "doGet" method (at this point everything else is
commented out), I tried using the recommended statements. Both of them
elicited the same error message:

try {
// Class.forName("org.postgresql.Driver");
this.getClass().getClassLoader().loadClass("org.postgresql.Driver");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}

java.lang.ClassNotFoundException: org.postgresql.Driver
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.
java:1516)
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.
java:1361)
at nearbyGPS.NearByTest.doGet(NearByTest.java:59)
...

---where nearbyGPS is the package and NearByTest is the servlet class.

As an experiment I tried importing the Driver class directly, e.g.:

import org.postgresql.*;
--and the form--
import org.postgresql.Driver;

These import statements both compile without complaint. But the same
error occurs. I'm afraid that there must be something rather
fundamental that I am missing. Is there another stage (prior to the

servlet's "doGet") at which the "preloading" should occur?

I just tried placing the recommended connection code in the
constructor, and get exactly the same error message and stack trace.

Eclipse has the option of right-clicking the project and selecting
"Configure Build Path". On this project, the PostgreSQL JDBC driver is
listed alongside the JRE and Apache libraries.

The stack trace indicates code that is part of Apache. Is there
possibly something that has to be configured in Apache that is missing?

Many, many thanks in advance.

++++++++++++++++++++++++++++++++++++++++++++++++++++

Manohar Bhattarai

unread,
Jun 3, 2010, 12:15:51 AM6/3/10
to
I had the same problem of getting exception of class not found as you are getting. I have solved the problem by simply putting the jar file in CATALINA_HOME/lib/ directory. Then i restarted Eclipse.
And wow the driver was found. This was solved just yesterday. See if this helps you.

BTW, now I am getting new exception of"password authentication". Just trying to solve this.

--
Regards,
Manohar Bhattarai (मनोहर भट्टराई)
Blogs:
http://manoharbhattarai.wordpress.com/
http://manoharbhattarai.posterous.com/
http://manoharbhattarai.blogspot.com/
Microblogs:
Twitter :- http://twitter.com/manoharmailme
Identi.ca :- http://identi.ca/manoharbhattarai

Craig Ringer

unread,
Jun 3, 2010, 1:52:26 AM6/3/10
to
On 3/06/2010 12:15 PM, Manohar Bhattarai wrote:

> I had the same problem of getting exception of class not found as you
> are getting. I have solved the problem by simply putting the jar file in
> CATALINA_HOME/lib/ directory. Then i restarted Eclipse.
> And wow the driver was found. This was solved just yesterday. See if
> this helps you.

That's usually not the best way to do it (at least in Glassfish-land)
though, because that jar is visible to all installed apps. It gets
complicated if different servelets require different versions of some
libraries.

If you're using .war packaging, you should be able to get Eclipse to
include the required jar in the package. In NetBeans it "just works"
(especially with Maven war packaging) but perhaps Eclipse needs a bit
more help.

--
Craig Ringer

Craig Ringer

unread,
Jun 3, 2010, 2:23:15 AM6/3/10
to
On 3/06/2010 6:58 AM, Lew wrote:


>> You can use the classloader that loaded the currently running object
>> with:
>>
>> this.getClass().getClassLoader().loadClass('org.postgresql.Driver');
>
> The driver should be loaded in a static context, not an instance
> context. Furthermore, that code as shown will not compile.

Oops, wrong quotes. Point.

> Further
> furthermore, I see nothing in the documentation for
> 'ClassLoader#loadClass()' that promises to initialize the class, unlike
> 'Class.forName()'. If the class is not initialized, the driver won't
> register with the 'DriverManager'. I think you're selling a pig in a
> poke here.

Fair call - the beahaviour would depend on the classloader, and probably
shouldn't be assumed.

> Go with the Tomcat way and forget the kludgey direct uses of Java
> reflection.

The fact that I haven't done much in servelet environments kinda shows,
I suspect. JNDI is certainly the way to go based on what you referred to.

--
Craig Ringer

Guy Rouillier

unread,
Jun 3, 2010, 7:51:17 PM6/3/10
to
On 6/3/2010 1:52 AM, Craig Ringer wrote:
> On 3/06/2010 12:15 PM, Manohar Bhattarai wrote:
>
>> I had the same problem of getting exception of class not found as you
>> are getting. I have solved the problem by simply putting the jar file in
>> CATALINA_HOME/lib/ directory. Then i restarted Eclipse.
>> And wow the driver was found. This was solved just yesterday. See if
>> this helps you.
>
> That's usually not the best way to do it (at least in Glassfish-land)
> though, because that jar is visible to all installed apps. It gets
> complicated if different servelets require different versions of some
> libraries.

I don't know the OP's configuration, but in Tomcat a common way to
handle database connections is to use the Tomcat-provide pooling
mechanism. If this option is chosen, then you must get the appropriate
database drivers into Tomcat's bootstrap classpath. Tomcat initializes
the connection pools before starting up any of the webapps, so putting
the database JARs into a particular webapp won't work.

If you elect not to use Tomcat's database pools, then of course you can
include the database drivers in with your application. But then if you
have 3 or 4 applications using the same database, each will have its own
connection pool, which is sub-optimal.

--
Guy Rouillier

phil...@aol.com

unread,
Jun 4, 2010, 1:48:20 AM6/4/10
to
HI - Thank you both Craig and Manohar.

There is no .WAR file in this project. So I am unable to follow related
advice.

There is a .CLASSPATH file stored with the project. It has the
following entry pertaining to the jdbc:
<classpathentry kind="con"
path="org.eclipse.datatools.connectivity.jdt.DRIVERLIBRARY/PostgreSQL
JDBC Driver"/>

There is also a .project file with various <buildSpec> and
<buildCommand> tags, and a .jsdtscope file with <classpath> and
<classpathentry> tags. But neither has any reference to the JDBC.

I'm thinking maybe I will refer back to the Eclipse Forum with this
research, as they will may know better if the registration is correct
and proper.

If I do get an answer, I will follow up here just in case anyone else
ends up pursuing the same matter.

With much appreciation,

Phil Freihofner

John R Pierce

unread,
Jun 4, 2010, 2:40:36 AM6/4/10
to
phil...@aol.com wrote:
> HI - Thank you both Craig and Manohar.
>
> There is no .WAR file in this project. So I am unable to follow
> related advice.

why not ? a .war file is the standard method of deploying a tomcat
app. its a renamed .zip file that contains the project jars, xml
manifest, related libraries, etc etc. to deploy the app (or an update)
you simply drop the .war into the deployment dir, and tomcat sees it and
unzips it into the /webapps/appname/ folder and off it goes

Lew

unread,
Jun 5, 2010, 9:20:55 AM6/5/10
to
phil...@aol.com wrote:
>> There is no .WAR file in this project. So I am unable to follow
>> related advice.

John R Pierce wrote:
> why not ? a .war file is the standard method of deploying a tomcat app.

My guess is that the OP didn't build the project, then.

> its a renamed .zip file that contains the project jars, xml manifest,
> related libraries, etc etc. to deploy the app (or an update) you simply
> drop the .war into the deployment dir, and tomcat sees it and unzips it
> into the /webapps/appname/ folder and off it goes

phil...@aol.com wrote:
>> There is a .CLASSPATH file stored with the project.

It's actually a ".classpath" file. This is an Eclipse-specific file and only
instructs Eclipse how to set the classpath. It does not itself set the classpath.

The classpath for a web app is entirely under the programmer's control and
depends on putting the driver JAR in the WAR. The entry in the Eclipse
metafiles directs Eclipse to do that for you.

>> It has the following entry pertaining to the jdbc:
>> <classpathentry kind="con"
>> path="org.eclipse.datatools.connectivity.jdt.DRIVERLIBRARY/PostgreSQL JDBC Driver"/>

I find it convenient to do as Manohar suggested, "simply putting the jar file
in [the $]CATALINA_HOME/lib/ directory", because typically if one app needs to
access a particular database then many if not all apps in that app server will
need access to the same driver. It's only truly necessary if Tomcat itself
needs that driver, e.g., to handle authentication. Otherwise it should
suffice to put the JAR in the "WEB-INF/lib/" directory of the deployed app
(i.e., the WAR file).

philfrei, you do have a WAR file if you're deploying a web app. You must be
looking in the wrong place. Into what directory does Eclipse put its built files?

Also, did you read the Tomcat documentation? I posted a couple of relevant
links upthread.

--
Lew

phil...@aol.com

unread,
Jun 5, 2010, 3:11:38 AM6/5/10
to
This is to follow up with the solution I was given at the Eclipse
"Newbies" forum. Thank you Russell Bateman!

With a right-click on the project, and a selection of "Properties," one
can navigate to "Java EE Module Dependencies." At this point, one can
"select the utility project, JAR or classpath entry to add as a Web
Library dependency." One of the choices offered was in fact the
PostgreSQL JDBC Driver library. After checking the option box, I was
able to run the servlet and have it connect to the PostgreSQL database.

A further clue (which I overlooked until this afternoon) was that in
the "Markers" area was the following Classpath Warning:

Classpath entry
org.eclipse.datatools.connectivity.jdt.DRIVERLIBRARY/PostgreSQL JDBC
Driver will not be exported or published. Runtime
ClassNotFoundExceptions may result.

Indeed, the problem was that the Driver class from the JDBC was not
being found. But once the above checkbox was selected, the warning
disappeared.

Do I understand this, or all the suggestions given? Not a whole lot.
I'm guessing that somehow the Apache server is executing code that is
not referencing the usual Java packages and libraries, and it needs to
have these dependencies addressed. I can't say the location for this is
exactly intuitive. But then, I am totally new to this and maybe it will
start to make more sense as I get further along.

One person was asking why I have no WAR file. The code for this project
was started from scratch and a bit of cut-and-paste. It was not created
from a WAR and I have yet to package it into a WAR. Maybe that answers
his question?

Thanks again for everyone who took time to address this question!

Lew

unread,
Jun 5, 2010, 7:13:34 PM6/5/10
to
phil...@aol.com wrote:
> This is to follow up with the solution I was given at the Eclipse
> "Newbies" forum. Thank you Russell Bateman!

Please do not top-post.

> ...


> Do I understand this, or all the suggestions given? Not a whole lot. I'm
> guessing that somehow the Apache server is executing code that is not

The term "Apache server" usually means the Apache Web Server, httpd, not the
Tomcat application server of which you speak here.

> referencing the usual Java packages and libraries, and it needs to have
> these dependencies addressed. I can't say the location for this is

As has been pointed out before in this thread, Tomcat applications (servlets)
do reference the usual Java packages and libraries, in the usual places, as
defined for the application server and very, very well documented on the
Tomcat web site.
<http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html>

> exactly intuitive. But then, I am totally new to this and maybe it will
> start to make more sense as I get further along.

Especially if you read the linked documentation.

> One person was asking why I have no WAR file. The code for this project
> was started from scratch and a bit of cut-and-paste. It was not created
> from a WAR and I have yet to package it into a WAR. Maybe that answers
> his question?

Nope. You don't start Web projects with a WAR file - a WAR file is the
product of the project.

When you ask Eclipse to build the project, it's either building a WAR file or
the equivalent uncompressed directory structure subsidiary to a build directory.

I seem to recall that Eclipse, like NetBeans, builds the WAR file from your
project source, but I might be wrong - you might have to explicitly ask
Eclipse to do that. Why not take a look at the destination directory, i.e.,
the distribution directory specified in your Eclipse project, after a build?

--
Lew

0 new messages