ClassLoader and JDBC problem
hi everyone!
i found the Mckoi db on the web and tried to play with it. below is the beginning of app code that runs great from the command line with the following:
java -cp ../../mckoidb.jar:. SimpleApplicationDemo
however, after i tried that and got all happy, i decided to create a custom class loader in the code below, so the i could run the app as in:
java SimpleApplicationDemo
when i do that, the program throws the exception telling me about the path not being correct
the only mods i did to the original demo code is the 'import java.net.*;' and what i put in the comments - ' startd modified code' and 'end modified code'
by the way: i only get the exception when the following line is commented out: Class.forName("com.mckoi.JDBCDriver").newInstance();
when i uncomment it, (without touching ANYTHING ELSE) and run it with the "-cp" switch everything works perfectly. any thoughts on that? i'm working on a small standalone app and need to hook it up with a small standalone db. i would like to keep the user from ever having to know what a classpath is :> any help will be greatly appreciated :> - ps i'm running it on Max OS X
import java.sql.*;
import java.net.*;
public class SimpleApplicationDemo {
/**
* The demonstation 'main' method.
*/
public static void main(String[] args) {
System.out.println();
// Register the Mckoi JDBC Driver
try {
// - start modified code --
URL jar = new URL("file: ../../mckoidb.jar");
URL[] classPath = new URL[]{jar};
ClassLoader loader = URLClassLoader.newInstance(classPath);
Class db = Class.forName("com.mckoi.JDBCDriver", true, loader);
// - end modified code --
// below is the orginal code
//Class.forName("com.mckoi.JDBCDriver").newInstance();
}
catch (Exception e) {
System.out.println(
"Unable to register the JDBC Driver.\n" +
"Make sure the classpath is correct.\n" +
"For example on Win32; java -cp ../../mckoidb.jar;. SimpleApplicationDemo\n" +
"On Unix; java -cp ../../mckoidb.jar:. SimpleApplicationDemo");
return;
}
part of your code reads as
URL jar = new URL("file: ../../mckoidb.jar");
This will not throw you any exceptions but your protocol is a little out. So you ClassLoader will not be able to find you mckoidb.jar because you URL is incorrect
It should read as:
URL jar = new URL("file://../../mckoidb.jar");
Try it out :-)
... just tried that, still no luck :<
Have you tried this?String jarFile = "classes12.zip";java.net.URL jar = getClass().getResource(jarFile);java.net.URL[] classPath = new java.net.URL[]{jar};ClassLoader loader = java.net.URLClassLoader.newInstance(classPath);
i believe i got the loader loading, but now i'm getting another problem.
everything seems to work fine until the end of this chunk of code.
at the end the sql exception gets thrown with the message being:
"Unable to make a connection to the database.
The reason: No suitable driver"
should i maybe re post this to the JDBC forum?
//-
import java.sql.*;
import java.net.*;
public class SimpleApplicationDemo {
/**
* The demonstation 'main' method.
*/
public static void main(String[] args) {
System.out.println();
// Register the Mckoi JDBC Driver
try {
// - start modified code --
URL[] urlsToLoadFrom = new URL[]{new URL("file:../../mckoidb.jar")};
URLClassLoader loader = new URLClassLoader(urlsToLoadFrom);
Class JDBCDriver = Class.forName("com.mckoi.JDBCDriver", true, loader);
// - end modified code --
// below is the orginal code - when uncommented works with:
// java -cp ../../mckoidb.jar:. SimpleApplicationDemo
//Class.forName("com.mckoi.JDBCDriver").newInstance();
}
catch (Exception e) {
System.out.println(
"Unable to register the JDBC Driver.\n" +
"Make sure the classpath is correct.\n" +
"For example on Win32; java -cp ../../mckoidb.jar;. SimpleApplicationDemo\n" +
"On Unix; java -cp ../../mckoidb.jar:. SimpleApplicationDemo");
return;
}
// This URL specifies we are connecting with a local database. The
// configuration file for the database is found at './ExampleDB.conf'
String url = "jdbc:mckoi:local://ExampleDB.conf";
// The username/password for the database. This is set when the database
// is created (see SimpleDatabaseCreateDemo).
String username = "user";
String password = "pass1212";
// Make a connection with the database.
Connection connection;
try {
connection = DriverManager.getConnection(url, username, password);
}
catch (SQLException e) {
System.out.println(
"Unable to make a connection to the database.\n" +
"The reason: " + e.getMessage());
return;
}
Not sure what the question is, but just to clarify...
you can't load a jdbc driver using a classloader.
At least not like other classes. (I believe that is the general consensus in the jdbc forum.)
Someone, in the jdbc forum, found an alternative solution for dynamic driver loading. You will have to search to find it.
Hi tomek_vector,
Okie dokie, this is what happened in your code.
1) you loaded your mckoid.jar driver on a different classloader. ie. loader
2) you are attempting to get the connection with the classloader which your SimpleApplicationDemo is on.
ie. you are on different ClassLoaders when you loaded the JDBC driver and when you attempt to get the database connection are different. This cannot be done. You must be on the same ClassLoader
What I would do is:
a) have another main program create the ClassLoader.
b) load the orginal SimpleApplicationDemo with this ClassLoader. (see (a))
c) now instantiate the SimpleApplicationDemo. (your code must be in the constructor)
Now everything would be rosy :-)
Regards,
Noel
>
> you can't load a jdbc driver using a classloader.
>
I disagree with this. Our very first "Hello World" program is loaded with the SystemClassLoader in the first place. Plus the fact that I have created an application with everything running on a ClassLoader which I defined. this includes the JDBC driver.
> >
> > you can't load a jdbc driver using a classloader.
> >
>
>
> I disagree with this. Our very first "Hello World"
> program is loaded with the SystemClassLoader in the
> first place. Plus the fact that I have created an
> application with everything running on a ClassLoader
> which I defined. this includes the JDBC driver.
>
It would be better to say that you cannot create a Connection using java.sql.DriverManager for a JDBC driver when your getConnection() call is running in a classloader different from the one used to load the JDBC driver. If all your code is loaded using the same custom classloader it would probably work although I haven't tried it.
Col
... i'll give this a whack, just running short on time here :>, thanks for the tips so far