Working in a multi version environment I found my self quite often receiving a .class file compiled with the wrong compiler version. Usually receiving a .class file compiled with JDK6 whereas I was working in an environment running with JRE5.
The problem is quite simple to understand when you get it during run-time, but unfortunately you sometimes only discover it after giving the customer a hot-fix for a problem only to discover you compiled with the wrong settings. Or sometimes just to test your code you need to bounce the file between several ftp sites just to get it to the run-time environment.
So I sat a few minutes and analyzed the “header” of the binary .class file and found a simple way to know if it was compiled for Java5, or for Java6.
Open it in any HEX viewer/editor and you can see the answer:
The 8th bit (byte #7 in HEX view) is equal to 0x31 for Java5 and 0x32 for Java6.
Just a note: 0x31=49 and 0x32=50, and 49 & 50 are the major versions for Java5 & Java6
Below you can see samples of the beginnings of two .class files:
It is important to mention that the above is a bit inaccurate but it is more than enough for the existing versions of Java and for the problem at hand.
The accurate definition of the .class file’s header is as such (taken from the Java 2nd edition Spec):
- Bytes 0-3: Magic Number (Value is always – 0xCAFEBABE)
- Bytes 4-5: Minor Version (Stored in big-endian format)
- Bytes 6-7: Major Version (Stored in big-endian format)
- So byte #7 (the 8th byte) is the less important byte of the 16bit unsigned integer that represents the Major Version. So when we reach Major Version 256 – the 8th byte will not be enough and I’ll have to revise this post.
When I first found out that Java class files could be decompiled I was shocked at how much my code is “unsafe”. That was several years ago. After getting over myself I understood the power in allowing the world to view my code and to view the code of the rest of the world – particularly that of the Java framework. I got introduced to a very nice tool named ‘JAD‘ (AFAIK it stands for Java Decompiler). The tool had the ability to decompile Java class files easily but had problematic defaults. I had to wrap it in a utility batch file to make it easier to work with – so I sat with two colleagues and together we compiled this nice batch file:
# General variables used later in the script set JAD="c:\Utils\jad.exe" set EDITOR="c:\Utils\Notepad++\notepad++.exe" set TEMP_DIR=c:\utils\decompiled # Part 1 - Take the name of the .class file and calculate the full path of the decompiled .java file set CLASS_NAME=%1% set CLASS_NEW_NAME=%CLASS_NAME:"=% set JAD_FULL_NAME=%CLASS_NEW_NAME:class=java% set JAD_NAME=%JAD_FULL_NAME:\= % for %%i in (%JAD_NAME%) do set JAD_NEW_NAME=%TEMP_DIR%\%%i # Part 2 - Decompile the .class file and redirect the output of the decompilation into the target .java file %JAD% -lnc -p %CLASS_NAME% > %JAD_NEW_NAME% # Part 3 - Open the selected text editor in the background with the decompiled .java file START /B %EDITOR% "%JAD_NEW_NAME%"
To use it you must perform two steps:
- Change the paths to whatever paths you like on your PC
- Open a .class file with your file browser and associate in windows that .class files should be opened with this batch file.
Once done – anytime you open a .classfile by double clicking on it or right-click and choosing ‘Open’ it will invoke the script and open the decompiled source. Script explanation in steps:
- Set a few variables that will be used later in the script
- Take the name of the .class file and calculate the full path of the decompiled .java file
- Decompile the .class file and redirect the output of the decompilation into the target .java file
- Open the selected text editor in the background with the decompiled .java file
The script and ‘JAD‘ executable can be downloaded from my public share at: ‘JAD.zip‘JAD is no longer being maintained by anyone to the best of my knowledge – so I hope it will not disappear (although there are plenty of alternatives). Two useful links about JAD: