tags:

views:

139

answers:

6

How can I tell what version of the Java compiler was used to build a jar? I have a jar file, and it could have been built in any one of three JDKs. We need to know exactly which one, so we can certify compatibility. Is the compiler version embedded somewhere in the class files or jar?

+4  A: 

You can't tell from the JAR file itself, necessarily.

Download a hex editor and open one of the class files inside the JAR and look at byte offsets 4 through 7. The version information is built in.

http://en.wikipedia.org/wiki/Class_(file_format)

Jonathon
To be pedantic, those bytes tell you what version the class has been compiled FOR, not what version compiled it. Java allows you to compile code so that they're compatible with earlier versions of Java. However, this only applies to byte code and format. It will happily compile code that references JDK 6 libraries into a JDK 5 format, for example. The JDK 5 will load the class, but can't run it as the JDK 5 library doesn't have the code referenced from JDK 6.
Will Hartung
+1  A: 

You can tell the Java binary version by inspecting the first 8 bytes (or using an app that can).

The compiler itself doesn't, to the best of my knowledge, insert any identifying signature. I can't spot such a thing in the file VM spec class format anyway.

McDowell
+4  A: 

The Java compiler (javac) does not build jars, it translates Java files into class files. The Jar tool (jar) creates jars. If no custom manifest was specified, the default manifest will specify which version of the JDK was used to create the jar.

jackrabbit
+1  A: 

Each class file has a version number embedded for the byte code level which the JVM use to see if it likes that particular byte code chunk or not. This is 48 for Java 1.4, 49 for Java 1.5 and 50 for Java 6.

Many compilers exist which can generate byte code at each level, javac uses the "-target" option to indicate which byte code level to generate, and the Java 6 javac can generate byte code for at least 1.4, 1.5 and 6. I do not believe that the compiler inserts anything that can identify the compiler itself which is what I think you ask for. Also the Eclipse compiler is increasingly being used, as it is a single jar which can run with the JRE only.

In a jar file there is usually many classes, and each of them is independent, so you need to investigate all classes in the jar to be certain about the characteristics of the contents.

Thorbjørn Ravn Andersen
+1  A: 

As as Peter Lawrey mentioned, you can't necessarily know which JDK release built the class, but you can find out the byte code class version.

On my Linux system, file(1) knew the class version. Extract a class from a jar and use file to identify it:

$ jar xf log4j-1.2.15.jar
$ file ./org/apache/log4j/Appender.class
./org/apache/log4j/Appender.class: compiled Java class data, version 45.3

A different class version, for example:

$ file ~/bin/classes/P.class
/home/dave/bin/classes/P.class: compiled Java class data, version 50.0

The class version major number corresponds to the following Java JDK versions:

  • 46 = Java 1.2
  • 47 = Java 1.3
  • 48 = Java 1.4
  • 49 = Java 5
  • 50 = Java 6
unhillbilly