1

I want to taste the newest Java 19 feature, also do not change the default Java Home( Java 17).

So I create a toolchains.xml in the ~/.m2, and define a jdk type toolchain like this.

<?xml version="1.0" encoding="UTF-8"?>
<toolchains>
  <!-- JDK toolchains -->
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.8</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>D:/jdks/jdk8</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>11</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>D:/jdks/jdk11</jdkHome>
    </configuration>
  </toolchain>
   <toolchain>
    <type>jdk</type>
    <provides>
      <version>17</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>D:/jdks/jdk17</jdkHome>
    </configuration>
  </toolchain>
    <toolchain>
    <type>jdk</type>
    <provides>
      <version>19</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>D:/jdks/jdk-19</jdkHome>
    </configuration>
  </toolchain>
  <!-- other toolchains -->
  <toolchain>
    <type>netbeans</type>
    <provides>
      <version>15</version>
    </provides>
    <configuration>
      <installDir>D:/devtools/netbeans</installDir>
    </configuration>
  </toolchain>
</toolchains>

Then I added the following plugins in my project POM.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.10.1</version>
    <configuration>
        <compilerArgs>
            <arg>--enable-preview</arg>             
        </compilerArgs>
        <encoding>${project.build.sourceEncoding}</encoding>
    </configuration>
</plugin>
<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>19</version>
                <vendor>oracle</vendor>
            </jdk>
        </toolchains>
    </configuration>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <mainClass>com.example.demo.RecordPatternExample</mainClass>
        <commandlineArgs>--enable-preview</commandlineArgs>
        <arguments>
            <argument>--enable-preview</argument>
        </arguments>
    </configuration>
</plugin>

As suggested in this question, I also added --enable-preview to the .mvn/jvm.config.

But when running the project in command line.

mvn clean package exec:java

I still got the exception like this.

[INFO] --- maven-compiler-plugin:3.10.1:compile (default-compile) @ record-pattern ---
[INFO] Toolchain in maven-compiler-plugin: JDK[D:/jdks/jdk-19]
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to D:\hantsylabs\java-sandbox\record-pattern\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ record-pattern ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\hantsylabs\java-sandbox\record-pattern\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:testCompile (default-testCompile) @ record-pattern ---
[INFO] Toolchain in maven-compiler-plugin: JDK[D:/jdks/jdk-19]
[INFO] Changes detected - recompiling the module!
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ record-pattern ---
[INFO] Toolchain in surefire-plugin: JDK[D:/jdks/jdk-19]
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ record-pattern ---
[INFO] Building jar: D:\hantsylabs\java-sandbox\record-pattern\target\record-pattern-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- exec-maven-plugin:3.1.0:java (default-cli) @ record-pattern ---
[WARNING]
java.lang.UnsupportedClassVersionError: com/example/demo/RecordPatternExample has been compiled by a more recent version of the Java Runtime (class file version 63.65535), this version of the Java Runtime only recognizes class file versions up to 61.0

Obviously the --enable-preview option was not applied with exec:java and toolchain configured JDK, but it worked well with maven-compiler-plugin.

The sample project is shared on my Github.

Hantsy
  • 8,006
  • 7
  • 64
  • 109
  • `toolchain.xml` or `toolchains.xml`? should be the latter, but you wrote the former. did the compiler plugin pick up your toolchain configuration? – eis Oct 11 '22 at 13:51
  • Yes, it is `toolchains.xml`. The compiler plugin is working well and picked up the `--enable-preview` arguments. But there is no way to make exec plugin working as expected. – Hantsy Oct 11 '22 at 14:43
  • the error message does not seem to be about not having `--enable-preview`, but not using toolchain configuration altogether. However, if compiler plugin picked up the new toolchain, so should exec:java. – eis Oct 11 '22 at 19:18
  • is your toolchains.xml somewhere in its entirety? don't see it in the github repo – eis Oct 11 '22 at 19:21
  • can you also please try running `mvn toolchains:toolchain exec:java` and see if that works – eis Oct 11 '22 at 19:23
  • Did not work. I have run the `mvn clean package exec:java` again, and updated the whole log of `compile`, `testCompile` and `test`, and `exec:java`, it seems `exec` does not run against the toolchain configured JDK. – Hantsy Oct 12 '22 at 01:22
  • From the [exec plugin doc](https://www.mojohaus.org/exec-maven-plugin/examples/example-exec-using-toolchains.html), jdk type toolchain should be enabled by default. – Hantsy Oct 12 '22 at 01:37
  • did you add your full toolchains.xml somewhere so we can see it? – eis Oct 12 '22 at 08:45
  • @eis Updated and pasted my complete toolchains.xml. – Hantsy Oct 12 '22 at 09:38

1 Answers1

1

Investigated this, and to me it seems this cannot be done: exec:java doesn't seem to have toolchains support. If you look at ExecJavaMojo source code which is used for exec:java, you see it has no references to toolchain, so it can't work. Compare that with ExecMojo source code that has them.

If you change your configuration to use exec:exec instead, setup should work:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <executable>java</executable>
        <arguments>
            <argument>--enable-preview</argument>
            <argument>-classpath</argument>
            <classpath/>
            <argument>com.example.demo.RecordPatternExample</argument>
        </arguments>
    </configuration>
</plugin>

Test run using mvn exec:exec with toolchains configured:

[INFO] --- exec-maven-plugin:3.1.0:exec (default-cli) @ record-pattern ---
[INFO] Toolchain in exec-maven-plugin: JDK[C:/Program Files/Java/jdk-19+36]
Hantsy Bai
Circle with r:1.2, area:4.5216
Square with x:1.2, area:1.44
Rectangle with x: 1.0 and y:2.0, area:2.0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.350 s
[INFO] Finished at: 2022-10-12T13:25:56+03:00
[INFO] Final Memory: 10M/25M
[INFO] ------------------------------------------------------------------------
eis
  • 51,991
  • 13
  • 150
  • 199
  • It seems like a bug. – Hantsy Oct 12 '22 at 12:37
  • 1
    @Hantsy toolchain support might not be possible to implement with exec:java. The point of that goal is to execute in the same VM as maven run, and it might not be possible to use some other toolchain within the same VM. – eis Oct 13 '22 at 07:51
  • 1
    As the documentation doesn't claim exec:java supports toolchains, I'm thinking rather a missing feature than a bug. – eis Oct 13 '22 at 08:09
  • I hope it is enabled by default when running application(align with compiler and surefire plugins), and use a configuration option to select use toolchain or not. Like we use NetBeans IDE(eg. use Java 19 to start) to build a Java 11 project(select a different JDK for project), when build and run the project in IDE, we never use the IDE scoped Java 19. – Hantsy Oct 13 '22 at 10:09