« July 2006 »
SunMonTueWedThuFriSat
      
1
2
5
7
8
9
10
11
13
14
16
19
20
21
23
24
25
26
29
30
     
Today
XML

Blog::Navigation

GetJava Download Button
Get the Source
Personal Blog

Blog::Referers

Today's Page Hits: 1026

Powered by Roller Weblogger.
« Previous day (Jul 26, 2006) | Main | Next day (Jul 28, 2006) »
20060728 Friday July 28, 2006

Thou shall know the .class file version!

It is easy to have more than on JDK or JRE version(in particular JRE -- because of browser plugin downloads!) in the same machine. If you compile your Java source(s) with a JDK version and run the same with with an earlier JDK/JRE version, you could get an error that looks like this:


Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file

Now, how do I know what is the version of a .class file and what version of JDK I need to run the same? The section 4.1 of VM spec. edition 2 explains the "header" structure of every .class file:


ClassFile {
    	u4 magic;
    	u2 minor_version;
    	u2 major_version;
    	u2 constant_pool_count;
    	cp_info constant_pool[constant_pool_count-1];
    	u2 access_flags;
    	u2 this_class;
    	u2 super_class;
    	u2 interfaces_count;
    	u2 interfaces[interfaces_count];
    	u2 fields_count;
    	field_info fields[fields_count];
    	u2 methods_count;
    	method_info methods[methods_count];
    	u2 attributes_count;
    	attribute_info attributes[attributes_count];
    }

The magic of a .class file is 0xCAFEBABE. The following class takes a class file as input and prints the major, minor version of it and also prints minium JDK/JRE required to run the given class.

File: Version.java

import java.io.*; public class Version { public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: java version <.class file>"); System.exit(1); } if (! new File(args[0]).exists()) { System.err.println(args[0] + " does not exist!"); System.exit(2); } DataInputStream dis = new DataInputStream( new FileInputStream(args[0])); int magic = dis.readInt(); if (magic != 0xcafebabe) { System.err.println(args[0] + " is not a .class file"); System.exit(3); } int minor = dis.readShort(); int major = dis.readShort(); System.out.println("class file version is " + major + "." + minor); String version = null; if (major < 48) { version = "1.3.1"; } else if (major == 48) { version = "1.4.2"; } else if (major == 49) { version = "1.5"; } else if (major == 50) { version = "6"; } else { version = "7"; } System.out.println("You need to use JDK " + version + " or above"); } }

For example, after compiling the above class with JDK 1.5 and running it against itself prints the following:

java -cp . Version Version.class
class file version is 49.0
You need to use JDK 1.5 or above



( Jul 28 2006, 07:52:22 PM IST ) Permalink Comments [5] del.icio.us | furl | simpy | slashdot | technorati | digg

Article on "scripting for the Java platform"

John O'Conner has written a nice article on scripting for the Java platform. This is a well written article with sample code. One minor thing: there was a change in javax.script.Invocable interface after the article was written/reviewed. You may have to change the downloaded code -- if you are working with Mustang build 91 or above.



( Jul 28 2006, 10:49:57 AM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

Copyright (C) 2005, A. Sundararajan's Weblog