I did a lot of
when trying to figure out how to set the classpath when executing a jar so I thought I would share what I found.
I searched through the beginner, intermediate, and advanced forums (and used google) and found the same question had been asked many times but did not find any single answer that completely worked for me.
So here goes (if I screw anything up hopefully someone more knowledgable then I will set me straight):
Suppose I have a class file, JdbcTest.class in this case, that makes use of the Microsoft SQL Server
JDBC driver. To use the driver (via Class.forName) I will need to ensure that the
java runtime environment knows how to reach the driver by either setting an environment variable called classpath that contains the full path or by passing the classpath to the runtime using the -cp flag (preferred method from what I understand).
ex:
c:\Projects\java\JDBCtest2>java -cp "C:\Program Files\Microsoft SQL Server 2005 JDBC Driver\sqljdbc_1.0\enu\sqljdbc.jar;." JdbcTest
I believe that the character used to separate filepaths in the classpath is platform dependent. In my case I am using Windows XP so it is ';' .
Note that I've included two paths: the path to the driver (which must include the name of the jar itself) and the current path '.'. If you specify a class path using the environment variable or the cp flag you must include the current path also. Here's the error message I get if I don't:
Exception in
thread "main" java.lang.NoClassDefFoundError: JdbcTest
Okay, but what if I want to place JdbcTest.class into a jar (test.jar)? Can I just do something like this?
C:\Projects\java\JDBCtest2>java -cp "C:\Program Files\Microsoft SQL Server 2005 JDBC Driver\sqljdbc_1.0\enu\sqljdbc.jar;." -jar test.jar
No! When you try to execute a jar the classpath is ignored. So you will get a ClassNotFoundException . You need to place the classpath in the jar's manifest file instead. Here is mine:
Main-Class: JdbcTest
Class-Path: \Progra~1\MIAA2F~1\sqljdbc_1.0\enu\sqljdbc.jar
Now there are several things to note here:
First, in the manifest file it is "Class-Path" and not "classpath".
Next, the current directory does not need to be included in the classpath. But if I were to include another path it would need to be separated by a space and not a semicolon.
That of course creates a problem on Windows when you have directories with spaces in their names. So what you have do is use the DOS short-name for any directory which has a space in its name. So in this example Program Files becomes Progra~1. Now the next directory in the path is Microsoft SQL Server 2005 JDBC Driver -- how in the world did that become MIAA2F? Well, it just so happens that I have 9 directories in my Program Files directory which start with Microsoft. The first by date created would be Micros~1, followed by Micros~2, Micros~3, and Micros~4. After that, however, the system changes--see this link:
(
http://www.microsoft.com/resources/documentation/windowsnt/4/workstation/reskit/en-us/diskdesc.mspx)
But you can use "dir /x" at the command prompt to discover the short-name for any file or directory which is how I figured out this one.
Also, the path to the external jar is relative to the path of my jar. Using drive names (c:\) will not work. I am not sure what you would need to do to list a path on another drive.
Lastly, remember that the manifest file must end with a new line or carriage return.
Hopefully, this helps someone.
Disclaimer: I am VERY new to java. I'm not sure that this method is the best way to access an external jar. If anyone out there has any more information to add I would
LOVE to hear it!