Am 2022-07-24 um 22:54 schrieb Andreas Sewe:
On 20.07.22 15:39, Karl Heinz Marbaise wrote:
On 20.07.22 13:04, Romain Manni-Bucau wrote:
 > There is no need to use toolchain to run your build with JDK17 and
 > create code for Java 8... you can use --release 8
 > (<maven.compiler.release>8</maven.compiler.release>)...
 >
 > No toolchain needed.

So you run tests with java 17? This is not what you want if your prod is
in java 8, you can still get surprises so you need toolchain in your
build (same happen for compilation since bytecode is not 1-1, only
signatures).

First what kind of surprises?

Second can you show an example of different bytes codes?

Just a regular Maven user here, but I'll give you an example, Karl Heinz, where testing against different Java versions was necessary to avoid shipping a blocker bug -- even though the bytecode didn't differ at all.

Some context: We maintain a couple of plug-ins for different IDEs (Eclipse, IntelliJ, NetBeans). Each plugin needs to be compatible with a whole range of IDE versions, as not all our users (can) use the latest and greatest. And different IDE versions usually mean different Java requirements, too.

In the case of the NetBeans plug-in (the same holds for Eclipse and IntelliJ, but these are build with Gradle and Maven+Tycho, respectively, rather than with plain Maven) this means that the plug-in needs to target Java 8 at the lower end, as older versions of NetBeans don't even run on the latest version of Java. Hence, we compile against Java 8.

However, we *also* occasionally test against newer versions of Java (e.g., in our nightly builds) to catch errors like the following:

The plug-in classloader of NetBeans [1] (and IntelliJ [2], FWIW) does not support multi-release JARs, which means that the following LOG4J2 statement fails when running on Java 9 or later.

     private static final Logger LOGGER = LogManager.getLogger();

As the plug-in classloader does not support the multi-release capabilities of the Log4J2 JAR, we end up in the Java 8 variant of getLogger(), which no longer works under newer versions of Java. The resulting ExceptionInInitializerError completely breaks our plug-in, but this luckily has been found during testing -- running the tests with Java 9 or later.

I hope this example was useful to the discussion at hand.

Now, at the moment we run Maven itself with Java 17 (as it speeds up our builds) and use toolchains to compile *and* test against Java 8. During our nightly build, however, we also pass in a system property which selects a different toolchain (ATM, Java 11).

This works, but is not ideal, as our nightly sanity build not only tests against Java 11 but also builds against it; both maven-compiler-plugin and maven-surefire-plugin use the *same* toolchain. Unfortunately, this means that we don't have a guarantee that the test against Java 11 use the same bytecode that we ship, since the nightly build compiles with the Java 11 but we have to ship the code compiled against Java 8 (i.e., our lowest denominator).

In an ideal world, our setup would look like this:

- mvn: Runs with Java 17
- maven-compiler-plugin: --release 8
- maven-surefire-plugin: a Java 8/11/17 toolchain, selected by system
     property

At the moment, we are not there yet, as we cannot use --release, as there cannot be separate toolchains for compilation and test. If that were to change with Maven 4, that would be great, of course.

Hope this helps.

As I said. Such an example and a move to Java 17 would cause just friction without any lubricant.

Reply via email to