Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / May 2008

Tip: Looking for answers? Try searching our database.

Dynamic classpath

Thread view: 
wizard of oz - 07 May 2008 09:41 GMT
I have a need to have a classpath that is determined by the set of jars a
user places into a directory.

By way of example, placing jar's into certain directories in a tomcat web
server will cause tomcat to include them into the web applications class
path. An example of this might be a charting package used by the web app to
generate charts.

In my specific example, I am building a query tool and I want to be able to
tell users to simply drop the JDBC drivers into a directory and my app will
"pick them up". Thus there would be no need to edit the classpath.

My target environment is Java 6.0

TIA
Thomas Kellerer - 07 May 2008 10:08 GMT
wizard of oz, 07.05.2008 10:41:
> I have a need to have a classpath that is determined by the set of jars
> a user places into a directory.
[quoted text clipped - 9 lines]
>
> My target environment is Java 6.0

You will need to use a URLClassLoader to load the driver(s)

The only problem is then doing the connection as the DriverManager will refuse to use a driver that was loaded by a different classloader.

You have two options to resolve this:

1) use Connection.connect(String, Properties) directly (bypassing DriverManager)
2) create a wrapper class that pretends to be a driver but delegates everything to the real instance (loaded by your own classloader).

I am using option 1) without any problems.

Thomas
wizard of oz - 07 May 2008 12:38 GMT
Can you post an example of Connection.connect (String, properties)?

My java doc says java.sql.Connection is an interface and doesn't mention a
connect method.

TIA

> wizard of oz, 07.05.2008 10:41:
>> I have a need to have a classpath that is determined by the set of jars a
[quoted text clipped - 24 lines]
>
> Thomas
Thomas Kellerer - 07 May 2008 13:17 GMT
Sorry, I meant Driver.connect()

Once you have loaded the driver class using a URLClassLoader, you can create a new instance and cast that to a Driver and then ask the driver to connect.

Something like this:

URLClassLoader l = new URLClassLoader(...);
Class drvClass = l.loadClass("org.postgresql.Driver");
java.sql.Driver drv = (java.sql.Driver)drvClass.newInstance();
Properties props = new Properties();
props.put("user", "postgres");
props.put("password", "password");

java.sql.Connection conn = drv.connect("jdbc:postgresql:localhost/mydb", props);

Regards
Thomas

wizard of oz, 07.05.2008 13:38:
> Can you post an example of Connection.connect (String, properties)?
>
[quoted text clipped - 32 lines]
>>
>> Thomas
wizard of oz - 08 May 2008 02:26 GMT
Cool, thanks.

> The only problem is then doing the connection as the DriverManager will refuse to use a driver that was loaded by a different classloader.

While I was awaiting your reply, I thought I would have a go at it myself. For what it is worth, the following also works. So the "standard method" of connecting to a database (via DriverManager) seems to work now (at least for my JDBC driver).
As mentioned I'm working in Java 6.0.

                  // For some reason my driver is in three parts
           URL jdbc1 = new URL ("file:/classpath/jars/JDBC/tdgssconfig.jar");
           URL jdbc2 = new URL ("file:/classpath/jars/JDBC/tdgssjava.jar");
           URL jdbc3 = new URL ("file:/classpath/jars/JDBC/terajdbc4.jar");
           
                           // Either of the following seem to work.
//            ClassLoader loader = new URLClassLoader (new URL [] { path, jdbc1, jdbc2, jdbc3 }, this.getClass().getClassLoader());
           ClassLoader loader = new URLClassLoader (new URL [] { path, jdbc1, jdbc2, jdbc3 });

           Class jdbcClass = loader.loadClass ("com.ncr.teradata.TeraDriver");
                            // The following is required otherwise I get a "No suitable driver" SQLException.
           Object jdbcDriver = jdbcClass.newInstance ();

           Connection c = DriverManager.getConnection("jdbc:teradata://dbc/", "uid", "pass");
           Statement s = c.createStatement();
           ResultSet r = s.executeQuery("select * from t1;");
           while (r.next()) {
               System.out.println (r.getString(1) + ", " + r.getString (2));
           }
           r.close ();
           s.close ();
           c.close ();

Thanks again for your post Thomas, it really helped point me in the right direction.

Glenn Mc

> Sorry, I meant Driver.connect()
>
[quoted text clipped - 13 lines]
> Regards
> Thomas
Lew - 08 May 2008 02:38 GMT
> Cool, thanks.

Please post to Usenet in plain text, not HTML.

Signature

Lew

wizard of oz - 08 May 2008 06:15 GMT
Spoke too soon. The following code *does* work in a test project, but not my
main project. Both projects are built using NetBeans 6.0.

The only difference I can pick is that the main project is a Swing project,
whereas the test project doesn't use Swing. Thomas's use of Driver.connect
does however work as he advertised.

Thanks again for all of the replies.

> Cool, thanks.
>
[quoted text clipped - 64 lines]
> > Regards
> > Thomas
Roedy Green - 07 May 2008 14:51 GMT
You can change the classpath on the fly by firing up a new
ClassLoader.
See http://mindprod.com/jgloss/classcloader.html
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Ian Shef - 15 May 2008 19:51 GMT
> You can change the classpath on the fly by firing up a new
> ClassLoader.
> See http://mindprod.com/jgloss/classcloader.html

In case it wan't obvious, I believe that Roedy meant

http://mindprod.com/jgloss/classloader.html
John B. Matthews - 16 May 2008 01:01 GMT
> > You can change the classpath on the fly by firing up a new
> > ClassLoader.
[quoted text clipped - 3 lines]
>
> http://mindprod.com/jgloss/classloader.html

Perhaps. The class java.tenebrous.ClassCLoader, now deprecated, is the
abstract superclass of all cassette tape loaders. It was one of the
first to implement the ScrollKeyboard interface, although it required
Ackerman(m,n) time to complete:-)

John
Signature

John B. Matthews
trashgod at gmail dot com
home dot woh dot rr dot com slash jbmatthews



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.