Wednesday, 12 December 2018

Java Versions - Compiled and Run-time

In the context of a client's Java application migration from Java 6 ( 1.6 ) to Java 8 ( 1.8 ), I wanted to show a colleague how we can typically run Java classes unmodified on Java 8, even though they were compiled using a much lower Java SDK ( JDK ).

I used two simple examples: -

Ferret


WebApp25


using this as inspiration: -


In both cases, I expanded the EAR / WAR files, and inspected one/more of the classes therein: -

mkdir /tmp/Ferret
cd  /tmp/Ferret
tar xvf ~/wlp/usr/servers/defaultServer/dropins/ferret-1.2.war

x META-INF/
x META-INF/MANIFEST.MF
x static/
x WEB-INF/
x WEB-INF/classes/
x WEB-INF/classes/net/
x WEB-INF/classes/net/wasdev/
x WEB-INF/classes/net/wasdev/samples/
x WEB-INF/classes/net/wasdev/samples/ferret/
x WEB-INF/classes/net/wasdev/samples/ferret/html/
x static/style.css
x WEB-INF/web.xml
x WEB-INF/classes/LICENSE
x WEB-INF/classes/net/wasdev/samples/ferret/FerretServlet.class
x WEB-INF/classes/net/wasdev/samples/ferret/html/Element.class
x WEB-INF/classes/net/wasdev/samples/ferret/html/Table.class
x WEB-INF/classes/net/wasdev/samples/ferret/html/Page.class
x WEB-INF/classes/net/wasdev/samples/ferret/html/Element$ElementType.class
x WEB-INF/classes/net/wasdev/samples/ferret/RequestData.class
x WEB-INF/classes/net/wasdev/samples/ferret/FerretData.class
x WEB-INF/ibm-web-ext.xml
x META-INF/maven/
x META-INF/maven/net.wasdev.wlp.sample/
x META-INF/maven/net.wasdev.wlp.sample/ferret/
x META-INF/maven/net.wasdev.wlp.sample/ferret/pom.xml
x META-INF/maven/net.wasdev.wlp.sample/ferret/pom.properties

...

javap -verbose WEB-INF/classes/net/wasdev/samples/ferret/FerretServlet.class|grep "major"

  major version: 51

mkdir /tmp/WebApp25
cd  /tmp/WebApp25
tar xvf ~/wlp/usr/servers/defaultServer/dropins/WebApp25EAR.ear

x META-INF/MANIFEST.MF
x META-INF/application.xml
x WebApp25.war


tar xvf WebApp25.war 

...
x META-INF/MANIFEST.MF
x WEB-INF/classes/com/ibm/fvt/filters/FilterWCSR001.class
x WEB-INF/classes/com/ibm/fvt/filters/FilterWCSR003.class
x WEB-INF/classes/com/ibm/fvt/filters/FilterWCSR007.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/CatchAll.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/ErrorPage.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/GetSession.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR001Error.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR001Forward.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR001Include.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR001Request.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR002.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR003.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR004.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR005.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR006.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR007.class
x WEB-INF/classes/com/ibm/ws/fvt/servlets/WCSR007a.class
x WEB-INF/ibm-web-bnd.xmi
x WEB-INF/ibm-web-ext.xmi
x WEB-INF/web.xml
x theme/Master.css
x WEB-INF/source/com/ibm/fvt/filters/FilterWCSR001.java
x WEB-INF/source/com/ibm/fvt/filters/FilterWCSR003.java
x WEB-INF/source/com/ibm/fvt/filters/FilterWCSR007.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/CatchAll.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/ErrorPage.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/GetSession.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR001Error.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR001Forward.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR001Include.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR001Request.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR002.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR003.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR004.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR005.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR006.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR007.java
x WEB-INF/source/com/ibm/ws/fvt/servlets/WCSR007a.java


javap -verbose WEB-INF/classes/com/ibm/ws/fvt/servlets/GetSession.class | grep "major"

  major version: 46

Using the lookup table from the Stackoverflow article: -

You're looking for this on the command line (for a class called MyClass):

On Unix/Linux:

javap -verbose MyClass | grep "major"
On Windows:

javap -verbose MyClass | findstr "major"
You want the major version from the results. Here are some example values:

• Java 1.2 uses major version 46
• Java 1.3 uses major version 47
• Java 1.4 uses major version 48
• Java 5 uses major version 49
• Java 6 uses major version 50
• Java 7 uses major version 51
• Java 8 uses major version 52
• Java 9 uses major version 53
• Java 10 uses major version 54
• Java 11 uses major version 55

I can see that Ferret ( version 51 ) was compiled for Java 7 and that WebApp25 ( version 46 ) was compiled for Java 1.2

And yet both run happily via the latest WebSphere Liberty Profile on Java 8…….

Nice.

No comments:

Note to self - use kubectl to query images in a pod or deployment

In both cases, we use JSON ... For a deployment, we can do this: - kubectl get deployment foobar --namespace snafu --output jsonpath="{...