0

I have my existing project that uses Java 1.8 My JAVA_HOME is set to Java 1.8 As a result maven is using Java 1.8 , which is fine Now our project has decided to start using SonarQube 9.x which runs on Java 11 In addition to run any scan / analysis of our code - it needs Java 11 as well

So here is what I need to be doing :

#1 Compile code using default jdk ( 1.8 ) ( mvn clean install )

#2 Run sonar scan using jdk 11 ( mvn sonar:sonar )

To execute #2 need maven to use jdk 11 while to execute #1 need maven to use jdk 1.8.

After reading various questions on SO came across 'toolchain'

So added toolchains.xml into my 'm2' folder :

<?xml version="1.0" encoding="UTF-8"?>
<toolchains>
 <!-- JDK toolchains -->
 <toolchain>
  <type>jdk</type>
  <provides>
   <version>1.11</version>
   <vendor>sun</vendor>
  </provides>
  <configuration>
   <jdkHome>C:\construction\tools\jdk-11.0.12</jdkHome>
  </configuration>
</toolchain>
<toolchain>
 <type>jdk</type>
 <provides>
  <version>1.8</version>
  <vendor>sun</vendor>
 </provides>
 <configuration>
  <jdkHome>C:\Program Files\Java\jdk1.8.0_191</jdkHome>
 </configuration>
</toolchain>  

Added toolchain plugin in my projects pom.xml

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-toolchains-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <goals>
                      <goal>toolchain</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <toolchains>
                    <jdk>
                        <version>1.11</version>
                        <vendor>sun</vendor>
                    </jdk>
                </toolchains>
            </configuration>
        </plugin>

Now when I run maven clean install can see in logs that java 11 'seems' to be used :

[INFO] --- maven-toolchains-plugin:1.1:toolchain (default) @ TreeSurveyAPI ---

[INFO] Required toolchain: jdk [ vendor='sun' version='1.11' ] [INFO] Found matching toolchain for type jdk: JDK[C:\construction\tools\jdk-11.0.12]

[INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ TreeSurveyAPI --- [INFO] Toolchain in maven-compiler-plugin: JDK[C:\construction\tools\jdk-11.0.12] [INFO] Changes detected - recompiling the module! [INFO] Compiling 11 source files to C:\construction\xxx\XYZ-main\target\classes

So it 'seems' that maven along with toolchain is using Java 11 to compile the code . However after executing javap against compiled class file indicates Major version as 52 ( Java 8 )

javap -verbose Abc.class | findstr "major"

So here are my questions :

#1 in the above case since toolchain points to java 11 shouldnt the code be compiled with java 11 ? why is it using java 8 ?

#2 How can I conditionally use java 8 Vs java 11 ( compile and build using java 8 and run sonar task using java 11 ) ?

Thanks

cb4
  • 6,689
  • 7
  • 45
  • 57
satish marathe
  • 1,073
  • 5
  • 18
  • 37
  • 1
    Wouldn't it be better to configure Java 8 just for the maven compile plugin? Then the build could run on Java 11 in both cases. – J Fabian Meier Nov 03 '21 at 11:41
  • Use JDK11 for build and define `--release` or via `maven.compiler.release` the target for the class files...that works perfectly fine...is easier etc. I would even think to go to build with JDK17 instead of JDK11... – khmarbaise Nov 03 '21 at 12:14
  • This is exactly the situation we have to deal with in our enterprise, and from my initial research, I believe (without testing yet) that the previous comment illustrates the basic strategy that should likely work. Note that you can also set the "release" property in the configuration of "maven-compiler-plugin", instead of setting the "target" and "source". – David M. Karr Nov 03 '21 at 17:59
  • Are you running mvn clean install from your IDE or from the terminal? – abbasdgr8 Nov 04 '21 at 05:50
  • from the command prompt – satish marathe Nov 05 '21 at 00:02

1 Answers1

0

You can run your project on java 11 also. It will run java 8 code no problem for 99% of the cases. This is what I would do. Therefore, upgrading the projects java version seems to be the easiest solution.

If this does not work, check out this answer

Also, if you need to be able to quickly change JVM versions for various tasks and in various folders, you can use this tool

Arthur Klezovich
  • 2,595
  • 1
  • 13
  • 17
  • thanks for the response but we are in a micoroservices world with 120+ api so running on java 11 will involve extensive regression which we do not want to do . Unfortunately in our environment introduction of this tool / new tool will be a challenge and it also seems to need additional work to get it to work on windows . I thought toolchain should help in changing jdk to be used ... – satish marathe Nov 03 '21 at 11:23
  • Got it. Then check out this answer https://stackoverflow.com/a/20787334/2599899 – Arthur Klezovich Nov 03 '21 at 11:27
  • Which regressions? Is the written code so heavily JDK specific or uses internals? – khmarbaise Nov 03 '21 at 12:15
  • thanks @ArthurKlezovich , however the answer in the so link is referring to change JAVA_HOME , now that would imply ( in my case ) to use default JAVA_HOME ( jdk1.8) to compile and build war / jar / ear which is fine , however in the next step I need to run sonar scan so need to change JAVA_HOME to JDK11 , I cannot do this manually and when I had tried to do this via command prompt ( with administrator priveleges ) it still would refuse to change to jdk11 – satish marathe Nov 03 '21 at 20:52
  • @khmarbaise in an earlier project we were forced to move our code from 1.6 to 1.7 ( code and project was inherited ) and one subtle bug introduced in production was the code was using reflection to get a list of methods and then firing calls to each of the method . The unfortunate part was that the code relied on reflection api to always return the methods in class in specific order ( which was the behaviour in 1.6 ) but after the issue cropped up in production ( and causing a lot of bad PR for me and our team ) , it was found that in jdk 1.7 reflection method order is not guaranteed .... – satish marathe Nov 03 '21 at 20:56
  • That sounds you seemed to have missing tests...which identified such things...in particular if you have made the experience... – khmarbaise Nov 04 '21 at 07:41
  • no the tests were present for regression , thing is on every startup of the jvm the order of methods could / would change , so tests were performed and it passed , even after it failed in prod , we were only able to reproduce it after restarting the component multiple times and then once in a while we were able to reproduce – satish marathe Nov 05 '21 at 00:02