4

I'm trying to find out how I can determine the version of a .class file by looking at its binary data. I know that using javap will tell me the version - but unfortunately I don't always have a JDK installed on the machine where I need to check. I do however have access to a plain old HEX editor ...

I tried finding documentation on this from a certified source - all I was able to come up was with this: http://fredericktang.wordpress.com/2007/09/28/java-class-file-version/
Although this blog post is very nicely written - it is not really backed up by official Java documentation.

Any hint?

Edit: Never mind - sorry to bug - I found the spec: here

2

2 Answers 2

4

The documentation you referenced is practically a word-for-word transcription (into easier English) of the JVM class file specification.

Some of the hitoric values I keep handy

Major  Major(hex) Minor Java platform version 
45     2d          3           1.0
45     2d          3           1.1
46     2e          0           1.2
47     2f          0           1.3
48     30          0           1.4
49     31          0           1.5
50     32          0           1.6

--- Edited in response to Neil's observation that 1.0 and 1.1 use the same Major Minor numbers ---

From the class header, one cannot determine whether the class was compiled against a 1.0 or 1.1 version of Java. That said, there are a number of other techniques that can help determine if a class was compiled against 1.0 or 1.1.

First, if the class was compiled against 1.1 it might have included a 1.1 only library class. Once you find one of these in one of the classes, you can safely conclude that it's a class compiled against Java 1.1.

Note that one may search the constant pool at the beginning of the class to determine which classes the class file will need to have all of its external references fully resolved.

It can be cumbersome to search for classes individually, fortunately a lot of packages were added too. The following packages are specific to Java 1.1, that is they were not included in Java 1.0

+ java.awt.datatransfer
+ java.awt.event
+ java.beans
+ java.lang.reflect
+ java.math
+ java.rmi.dgc
+ java.rmi
+ java.rmi.registry
+ java.rmi.server
+ java.security.acl
+ java.security
+ java.security.interfaces
+ java.sql
+ java.text
+ java.util.zip

On the other side of the fence, lots of calls to the following methods suggest (but are not actual proof) that the code was written against Java 1.0, as they were deprecated in Java 1.1 due to the new awt event restructuring.

Deprecated Classes

java.io.LineNumberInputStream:
    LineNumberInputStream is deprecated. 
java.io.StringBufferInputStream:
    StringBufferInputStream is deprecated. 

Deprecated Methods

java.awt.BorderLayout:
    addLayoutComponent() is deprecated. 
java.awt.CardLayout:
    addLayoutComponent() is deprecated. 
java.awt.CheckboxGroup:
    getCurrent() is deprecated. 
java.awt.CheckboxGroup:
    setCurrent() is deprecated. 
java.awt.Choice:
    countItems() is deprecated. 
java.awt.Component:
    getPeer() is deprecated. 
java.awt.Component:
    enable() is deprecated. 
java.awt.Component:
    enable() is deprecated. 
java.awt.Component:
    disable() is deprecated. 
java.awt.Component:
    show() is deprecated. 
java.awt.Component:
    show() is deprecated. 
java.awt.Component:
    hide() is deprecated. 
java.awt.Component:
    location() is deprecated. 
java.awt.Component:
    move() is deprecated. 
java.awt.Component:
    size() is deprecated. 
java.awt.Component:
    resize() is deprecated. 
java.awt.Component:
    resize() is deprecated. 
java.awt.Component:
    bounds() is deprecated. 
java.awt.Component:
    reshape() is deprecated. 
java.awt.Component:
    preferredSize() is deprecated. 
java.awt.Component:
    minimumSize() is deprecated. 
java.awt.Component:
    layout() is deprecated. 
java.awt.Component:
    inside() is deprecated. 
java.awt.Component:
    locate() is deprecated. 
java.awt.Component:
    deliverEvent() is deprecated. 
java.awt.Component:
    postEvent() is deprecated. 
java.awt.Component:
    handleEvent() is deprecated. 
java.awt.Component:
    mouseDown() is deprecated. 
java.awt.Component:
    mouseDrag() is deprecated. 
java.awt.Component:
    mouseUp() is deprecated. 
java.awt.Component:
    mouseMove() is deprecated. 
java.awt.Component:
    mouseEnter() is deprecated. 
java.awt.Component:
    mouseExit() is deprecated. 
java.awt.Component:
    keyDown() is deprecated. 
java.awt.Component:
    keyUp() is deprecated. 
java.awt.Component:
    action() is deprecated. 
java.awt.Component:
    gotFocus() is deprecated. 
java.awt.Component:
    lostFocus() is deprecated. 
java.awt.Component:
    nextFocus() is deprecated. 
java.awt.Container:
    countComponents() is deprecated. 
java.awt.Container:
    insets() is deprecated. 
java.awt.Container:
    layout() is deprecated. 
java.awt.Container:
    preferredSize() is deprecated. 
java.awt.Container:
    minimumSize() is deprecated. 
java.awt.Container:
    deliverEvent() is deprecated. 
java.awt.Container:
    locate() is deprecated. 
java.awt.FontMetrics:
    getMaxDecent() is deprecated. 
java.awt.Frame:
    setCursor() is deprecated. 
java.awt.Frame:
    getCursorType() is deprecated. 
java.awt.Graphics:
    getClipRect() is deprecated. 
java.awt.List:
    countItems() is deprecated. 
java.awt.List:
    clear() is deprecated. 
java.awt.List:
    isSelected() is deprecated. 
java.awt.List:
    allowsMultipleSelections() is deprecated. 
java.awt.List:
    setMultipleSelections() is deprecated. 
java.awt.List:
    preferredSize() is deprecated. 
java.awt.List:
    preferredSize() is deprecated. 
java.awt.List:
    minimumSize() is deprecated. 
java.awt.List:
    minimumSize() is deprecated. 
java.awt.List:
    delItems() is deprecated. 
java.awt.Menu:
    countItems() is deprecated. 
java.awt.MenuBar:
    countMenus() is deprecated. 
java.awt.MenuComponent:
    getPeer() is deprecated. 
java.awt.MenuComponent:
    postEvent() is deprecated. 
java.awt.MenuContainer:
    postEvent() is deprecated. 
java.awt.MenuItem:
    enable() is deprecated. 
java.awt.MenuItem:
    enable() is deprecated. 
java.awt.MenuItem:
    disable() is deprecated. 
java.awt.Polygon:
    getBoundingBox() is deprecated. 
java.awt.Polygon:
    inside() is deprecated. 
java.awt.Rectangle:
    reshape() is deprecated. 
java.awt.Rectangle:
    move() is deprecated. 
java.awt.Rectangle:
    resize() is deprecated. 
java.awt.Rectangle:
    inside() is deprecated. 
java.awt.ScrollPane:
    layout() is deprecated. 
java.awt.Scrollbar:
    getVisible() is deprecated. 
java.awt.Scrollbar:
    setLineIncrement() is deprecated. 
java.awt.Scrollbar:
    getLineIncrement() is deprecated. 
java.awt.Scrollbar:
    setPageIncrement() is deprecated. 
java.awt.Scrollbar:
    getPageIncrement() is deprecated. 
java.awt.TextArea:
    insertText() is deprecated. 
java.awt.TextArea:
    appendText() is deprecated. 
java.awt.TextArea:
    replaceText() is deprecated. 
java.awt.TextArea:
    preferredSize() is deprecated. 
java.awt.TextArea:
    preferredSize() is deprecated. 
java.awt.TextArea:
    minimumSize() is deprecated. 
java.awt.TextArea:
    minimumSize() is deprecated. 
java.awt.TextField:
    setEchoCharacter() is deprecated. 
java.awt.TextField:
    preferredSize() is deprecated. 
java.awt.TextField:
    preferredSize() is deprecated. 
java.awt.TextField:
    minimumSize() is deprecated. 
java.awt.TextField:
    minimumSize() is deprecated. 
java.awt.Window:
    postEvent() is deprecated. 
java.io.ByteArrayOutputStream:
    toString() is deprecated. 
java.io.DataInputStream:
    readLine() is deprecated. 
java.io.PrintStream:
    PrintStream() is deprecated. 
java.io.PrintStream:
    PrintStream() is deprecated. 
java.io.StreamTokenizer:
    StreamTokenizer() is deprecated. 
java.lang.Character:
    isJavaLetter() is deprecated. 
java.lang.Character:
    isJavaLetterOrDigit() is deprecated. 
java.lang.Character:
    isSpace() is deprecated. 
java.lang.ClassLoader:
    defineClass() is deprecated. 
java.lang.Runtime:
    getLocalizedInputStream() is deprecated. 
java.lang.Runtime:
    getLocalizedOutputStream() is deprecated. 
java.lang.String:
    String() is deprecated. 
java.lang.String:
    String() is deprecated. 
java.lang.String:
    getBytes() is deprecated. 
java.lang.System:
    getenv() is deprecated. 
java.net.Socket:
    Socket() is deprecated. 
java.net.Socket:
    Socket() is deprecated. 
java.util.Date:
    Date() is deprecated. 
java.util.Date:
    Date() is deprecated. 
java.util.Date:
    Date() is deprecated. 
java.util.Date:
    Date() is deprecated. 
java.util.Date:
    UTC() is deprecated. 
java.util.Date:
    parse() is deprecated. 
java.util.Date:
    getYear() is deprecated. 
java.util.Date:
    setYear() is deprecated. 
java.util.Date:
    getMonth() is deprecated. 
java.util.Date:
    setMonth() is deprecated. 
java.util.Date:
    getDate() is deprecated. 
java.util.Date:
    setDate() is deprecated. 
java.util.Date:
    getDay() is deprecated. 
java.util.Date:
    getHours() is deprecated. 
java.util.Date:
    setHours() is deprecated. 
java.util.Date:
    getMinutes() is deprecated. 
java.util.Date:
    setMinutes() is deprecated. 
java.util.Date:
    getSeconds() is deprecated. 
java.util.Date:
    setSeconds() is deprecated. 
java.util.Date:
    toLocaleString() is deprecated. 
java.util.Date:
    toGMTString() is deprecated. 
java.util.Date:
    getTimezoneOffset() is deprecated. 

It is possible to prove that Java code is version 1.1, but only in some cases (if the code uses newly added 1.1 features). It is generally impossible to prove that Java code was 1.0, but the lack of any use of Java 1.1 features, and heavy use of Java's deprecated features hints to classes targeted for the Java 1.0 environment.

I am unaware of any in-class tagging which might be able to differentiate the two (differences in line number tables, etc.), mostly because I haven't had the need to dig through 1.0 and 1.1 classes in a hex editor.

4
  • Either I don't understand your table, or some of those values don't make sense, or you've transcribed them incorrectly...
    – Neil
    Commented Apr 25, 2011 at 19:33
  • @Neil, sorry, i transcribed them incorrectly. I will fix them now.
    – Edwin Buck
    Commented Apr 25, 2011 at 20:46
  • OK, so I take it you can't distinguish between 1.0 and 1.1 from the class file?
    – Neil
    Commented Apr 26, 2011 at 19:15
  • @Neil, correct. You have to poke into the class's imports to see if a 1.1 class was referenced (like BigInteger). If you find such a class, it must be 1.1, otherwise it could be either 1.1 or 1.0. I'll add a bit to the answer (as it gets a bit complex).
    – Edwin Buck
    Commented Apr 26, 2011 at 19:41
2

The JVM specification is about as authoritative as you're going to get. Chapter 4 is probably what you're after.

1
  • Thanks - that was the link I was looking for (and managed to find eventually by myself :))
    – RonK
    Commented Apr 25, 2011 at 19:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.