1

I have a project that was compiled to an ear file using maven. This is what was used to compile the code:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <configuration>
        <source>1.6/source>
        <target>1.6</target>
    </configuration>
</plugin>

Is there a way I can determine what minor version of Java maven used to compile the code?

UPDATE:

I was able to get the major and minor version using just the ear file generated from the maven build by doing the following:

  • Extract the ear file using a zip file tool to get to the contained files
  • From the extracted files find one of the jars generated from my source code
  • run javap using the following (from the dir where the jar file exists):

javap -classpath ./myjarfile.jar -verbose -c com.myorg.myproj.MyClass

The beginning of the output looks like this:

Classfile jar:file:/C:/TEMP/myjarfile.jar!/com/myorg/myproject/MyClass.class
  Last modified May 26, 2017; size 944 bytes
  MD5 checksum 37996ea9840df04afb5485fedd861f8e
  Compiled from "MyClass.java"
public class com.myorg.myproj.MyClass extends com.myorg.myproj.SomeOtherClass
  SourceFile: "SomeOtherClass.java"
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_SUPER

So it looks like my class was compiled using Major Version 50 and Minor Version 0.

HOWEVER, The question remains, what specific version of Java was used to compile the code? I'm expecting something like what you would get back if you were to type "java -version" at a cmd prompt (e.g. java version "1.7.0_51").

What does 50.0 map to in terms of a "java -version" version?

There are a number of posts regarding this type of mapping, but they all seem to only map the major version. These include the following:

List of Java class file format major version numbers?

https://blogs.oracle.com/darcy/source%2c-target%2c-class-file-version-decoder-ring

http://www.rgagnon.com/javadetails/java-0544.html

Also, I don't seem to have a Java 1.6 environment installed on the machine where I compiled the code, so I'm not sure what maven used to compile the code to Java 1`.6.

John
  • 3,458
  • 4
  • 33
  • 54
  • 1
    It used whichever JDK it found by default on your system, or an overridden one if from an IDE. (That is capable of compiling and running 1.6) – jr593 Jun 14 '17 at 15:21
  • 1
    Maven prints which JAVA_HOME is being used. You can run java -version to see the exact build. – vempo Jun 14 '17 at 15:22
  • 1
    You can also open a .class file in a hex edition and check https://en.wikipedia.org/wiki/Java_class_file#General_layout – vempo Jun 14 '17 at 15:24
  • Maven doesn't compile the code, it runs a plugin that invokes a Java compiler (javac) to compile the code. – vempo Jun 14 '17 at 15:29
  • Regarding your last question, javac supports cross-compiling https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html#BHCIJIEG – vempo Jun 15 '17 at 01:07

2 Answers2

1

When you compile Java classes with Maven there are several actors at play, so you should understand version of what you are interested in.

If no custom configuration is used, Maven compiler plugin requires a Java compiler to run and will fail if you don't have a JDK (only JRE) on your machine. If you run the mvn command with -X (e.g. mvn -version -X), it will print detailed information about the Java installation it uses. In most cases the compiler from that installation will be used. Notice that Java home points to a JRE, but it's part of a JDK. You can find other useful information about the compiler plugin by running the build with -X.

Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 1.8.0_131, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre

Maven makes our lives even easier by including the build JDK version in the manifest (META-INF/MANIFEST.MF) of an artifact.

Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_121

Source and target versions

In order to generate 1.6 bytecode, a Java compiler does not necessary has to be of the same version . This is called "cross-compilation". So, your configuration will work also with JDK 1.7 and JDK 1.8. Regarding the source version (syntax), some source versions can be compiled to older bytecode, while some others can not. It may be important if you want to run your code on a JVM that is older than you used for development.

This is why you might be interested not in the JDK version used to compile source files, but in the version of resulting bytecode. As I suggested in a comment, open a .class file in a hexadecimal viewer/editor and reference Java class file - General layout to find out the version.

UPDATE: By the way, JVM bytecode does not have to be created by a Java compiler. There are JVM languages other than Java, but their compilers still generate bytecode that can run on a JVM. In this case it's meaningless to talk about a version of Java.

vempo
  • 3,093
  • 1
  • 14
  • 16
0

You really shouldn't need to require a specific version of the JDK. If you do, however, use this piece of XML that is shown on the Maven help site:

<configuration>
    <verbose>true</verbose>
    <fork>true</fork>
    <executable><!-- path-to-javac --></executable>
    <compilerVersion>1.3</compilerVersion>
</configuration>

Your path to JavaC would look something like this: C:\Program Files\Java\j2sdk1.4.2_09\bin\javac. Of course, you'd have to locate your actual Java JDK location.

CJ Burkey
  • 385
  • 1
  • 14
  • That is only the half of the truth cause the bootclasspath is missing. If you really need to compile with a particular JDK you have to use [toolchains](https://maven.apache.org/guides/mini/guide-using-toolchains.html)...Apart from that if you run your build this will run your tests with JDK the version which Maven is running with..which is not what you want... – khmarbaise Jun 15 '17 at 10:05