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
The code posted by Owen can tell you the information mentioned by a number of the other answers here:
public void simpleExample ()
{
FileInputStream fis = new FileInputStream ("mytest.class");
parseJavaClassFile ( fis );
}
protected void parseJavaClassFile ( InputStream classByteStream ) throws Exception
{
DataInputStream dataInputStream = new DataInputStream ( classByteStream );
magicNumber = dataInputStream.readInt();
if ( magicNumber == 0xCAFEBABE )
{
int minorVer = dataInputStream.readUnsignedShort();
int majorVer = dataInputStream.readUnsignedShort();
// do something here with major & minor numbers
}
}
See also this and this site. I ended up modifying the Mind Products code quickly to check what each of my dependencies was compiled for.
you can find Java compiler version from .class files using a Hex Editor.
Step 1: Extract .class files from jar file using a zip extractor
step 2: open .class file with a hex editor.(I have used notepad++ hex editor plugin. This plugin reads file as binary and shows it in hex) You can see below.
Index 6 and 7 gives major version number of the class file format being used. https://en.wikipedia.org/wiki/Java_class_file
Java SE 11 = 55 (0x37 hex)
Java SE 10 = 54 (0x36 hex)
Java SE 9 = 53 (0x35 hex)
Java SE 8 = 52 (0x34 hex),
Java SE 7 = 51 (0x33 hex),
Java SE 6.0 = 50 (0x32 hex),
Java SE 5.0 = 49 (0x31 hex),
JDK 1.4 = 48 (0x30 hex),
JDK 1.3 = 47 (0x2F hex),
JDK 1.2 = 46 (0x2E hex),
JDK 1.1 = 45 (0x2D hex).
One liner (Linux)
unzip -p mylib.jar META-INF/MANIFEST.MF
This prints the content of MANIFEST.MF
file to stdout (hopefully there is one in your jar file :)
Depending on what built your package, you will find the JDK version in Created-By
or Build-Jdk
key.
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/Java_class_file
Note: As mentioned in the comment below,
those bytes tell you what version the class has been compiled FOR, not what version compiled it.
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.
A jar
is merely a container. It is a file archive ā la tar. While a jar
may have interesting information contained within it's META-INF hierarchy, it has no obligation to specify the vintage of the classes within it's contents. For that, one must examine the class
files therein.
As as Peter Lawrey mentioned in comment to the original question, you can't necessarily know which JDK release built a given class
file, but you can find out the byte code class version of the class
file contained in a jar
.
Yes, this kinda sucks, but the first step is to extract one or more classes from the jar
. For example:
$ jar xf log4j-1.2.15.jar
On Linux, Mac OS X or Windows with Cygwin installed, the file(1) command knows the class version.
$ file ./org/apache/log4j/Appender.class
./org/apache/log4j/Appender.class: compiled Java class data, version 45.3
Or alternatively, using javap
from the JDK as @jikes.thunderbolt aptly points out:
$ javap -v ./org/apache/log4j/Appender.class | grep major
major version: 45
For Windows
environments without either file
or grep
> javap -v ./org/apache/log4j/Appender.class | findstr major
major version: 45
FWIW, I will concur that javap
will tell a whole lot more about a given class
file than the original question asked.
Anyway, 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: