Deploying Jar Files
I created an application with Sun Studio Enterprise 8.1. I built the Jar file and then moved it and its corresponding 'lib' directory to another box. When I run the application with the 'java -jar' command, I receive the following error:
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
Any advice?
[373 byte] By [
Aquinasa] at [2007-11-27 4:42:42]

# 1
'Unsupported Class Version' error usually occurs when a class is complied with a higher jdk but is run against a previous jdk.
Can you check the jdk version you are using for the ide (Help | About | Details) and the version you are using for running the jar ('java -version' on the command line)?
In the project properties dialog, you will see 'Source Level' combobox in the first panel. You can set the source level here. If you set the source level to 1.4, then you can run the ide under jdk5 or jdk6 and still run under jdk1.4 , because with this setting jdk will only produce 1.4 compatible binary classes.
# 2
Nice call. You were right. The machine I am compiling this on has a newer runtime environment....
Ok - next error. I downgraded the source level, everything compiles. I then zip up the dist folder. Before I ship to new machine, I unzip in a new directory and do a test run. Everything is still good. I ship to new machine, unzip and then run it. Program starts to run and then crashes with the following error: Exception in thread "main" java.lang.NoSuchMethodError: com.enterprisedt.net.ftp.FTPClient.put......etc...
One of the jar files packaged with the program is enterprisedt's ftp toolset. Isn't the dist folder suppose to act like a standalone application provided a suitable JRE is installed on the next machine? Please note: There is an older enterprisedt tool set on the machine i am transferring this program to however the older one also has the method the program is looking for. Any more thoughts?
# 3
This seems to be a classpath problem.
Have you tried running with a specific classpath and see if it works? For example:
java -classpath <myprog.jar>:dist\<mylib1.jar>... myprog ...
(; instead of colon if you are running on windows)
You can also try "java -verbose -classpath <myprog.jar>:dist\<mylib1.jar>... myprog ..." and see if the output gives any clue.
# 4
You are right. It insists on going after the old ftp.jar (in the global classpath) rather than looking at the new edtftpj-1.5.4.jar that is included in the lib directory. This is the file the program expects to see.
I can't see to force it to look at that jar file first.
BTW - this program runs fine on all other machines EXCEPT the one it was intended for.
How do I force it to look at its on library files FIRST before going to the rest of the classpath set up via the environment variable? When I try:
java -classpath lib\edtftpj-1.5.4.jar -jar Chat.jar
It still goes to the old ftp.jar library for the Method instead of to the edtftpj-1.5.4.jar file where it belongs.
# 5
According to http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html#options
-jar
Execute a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. In order for this option to work, the manifest of the JAR file must contain a line of the form Main-Class: classname. Here, classname identifies the class having the public static void main(String[] args) method that serves as your application's starting point. See the Jar tool reference page and the Jar trail of the Java Tutorial for information about working with Jar files and Jar-file manifests.
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
So, if you are using -jar option, then -cp will be ignored.
There are two ways to solve this:
1. Do not use -jar option.
You can try executing the mainclass directly as in:
java -classpath lib\edtftpj-1.5.4.jar:Chat.jar <mainclassname>
You need to add all necessary jars to classpath above; you should use ";" instead of ":" if you are running in windows; mainclassname should be just the basename (without the .class extension).
2. If you want to use -jar option, then the MANIFEST file of Chat.jar should speciify the classpath. (When you use -jar option, all other classpath settings are ignored and so classpath should come from manifest file).
Please take a look at http://forum.java.sun.com/thread.jspa?forumID=747&threadID=5060169 :
# 6
Unfortunately, neither of these methods work. They are not wrong. They work fine on other machines, but the machine this is intended for refuses to look at the classpath before it looks elsewhere for the Method. Since the old FTPClient from enterprisedt is in the machines default classpath (because it is part of the JRE's lib folder), it looks there and breaks when it does not find the Method. I realize I could upgrade the library (ftp.jar) on the main server, but I do not have a sandbox and after all these errors for a simple little script, I am concerned I would break existing programs by doing this. Do you have any other suggestions?
# 7
If a jar is found in jre's lib directory, then i think it will be placed before others as part of bootstrap.
There are a couple of things you can try:
1. Use -Xbootclasspath option
http://java.sun.com/javase/6/docs/technotes/tools/windows/java.html
Xbootclasspath:bootclasspath
Specify a semicolon-separated list of directories, JAR archives, and ZIP archives to search for boot class files. These are used in place of the boot class files included in the Java 2 SDK. Note: Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.
-Xbootclasspath/a:path
Specify a semicolon-separated path of directires, JAR archives, and ZIP archives to append to the default bootstrap class path.
2. Try running the program as 'java -verbose ...' to check how the classes are being loaded. You can also try 'System.out.println(System.getProperty("java.class.path"))' within your program.
But in general, if you would like to load from a specified jar, no matter what the classpath is, then i think the correct way to do that will be to roll out your own classloader.
http://java.sun.com/developer/technicalArticles/Networking/classloaders/index.h tml
# 8
I finally decided to make it easy on myself so I just compiled it using the same FTP library that is in use on the production machine for which the script is intended. Thank-you very much for your help. Although I can't say this was an auspicious beginning with a new programming language (it was my first Java program), your help was invaluable. I am still rather surprised that 'portable' programs cannot be forced to look at their own libraries first before using the machines - without a lot of extra work, but I guess the developers have their reasons. Thanks again!
# 9
Actually classpath issues are faced by everyone learning the Java language. In fact, most of the errors one sees in java related forums relate to classes not being found in the classpath.
As you have said, Java creators have their reasons for this apparent complexity but i myself have seen that things make sense as one codes more and more in java.
Glad you could get your problem solved.