Monday, December 14, 2020

What Version of Java Compiled This

Java's mascot, Tux the Penguin
I try to use the latest stable version of Java/JDK when I can. There are a lot of performance improvements in newer versions of Java. Newer versions of OpenJDK also allow usage of Java Flight Recorder (that's a big deal). So when I have to work with a new Java application I often start with a new version of Java and work my way down the list until everything works. This can be a painful experience. When I have less time I'll look up what version of Java was used to compile the application then use the same version to run it. Even if you do have free time this is a good idea because Java 8 and below is probably going to have problems running on Java 9 and beyond. A lot of core language classes changed.

You might be thinking, "Why is this?" That's a valid question. It comes down to poor testing. The people testing are using the same environment as the developers and don't see a problem. The class files provided by the JDK are available to the application to use. All required classes should have been bundled with the application, but if the issue isn't caught in testing then it doesn't happen.

Anyway, how to test this: if you have a JAR or WAR file unzip it. On Linux, you can just run the unzip command against the file: unzip example.jar. On Windows, if you have a third party application you can point it at the file. If you are using Windows' built-in zip handling then rename the file to end with a .zip.

Once the files are extracted navigate to a class file made by the provider of the application; something like, com/yoakum/oneZero/security/. On Linux run javap -verbose Example.class | grep "major" on Windows run javap -verbose Example.class | findstr "major". This will return a number which you'll match to the following table:

Class Major Version | Java Major Version
                 ...|...
                 15 | 59
                 14 | 58
                 13 | 57
                 12 | 56
                 11 | 55
                 10 | 54
                  9 | 53
                  8 | 52
                  7 | 51
                 ...|...

This isn't a problem unique to Java. Every programming language I've ever worked with has had this issue. Java shouldn't have this issue as badly as it does. And it wouldn't if businesses would put more effort into ensuring their applications were more fully packaged to remove risk of missing or conflicting versions of dependencies.