docker-maven icon indicating copy to clipboard operation
docker-maven copied to clipboard

Add the JDK to the default toolchains.xml

Open maffe opened this issue 2 years ago • 3 comments

It would be useful to have the JDK included in the default toolchains file.

Currently I have something like this in my pom.xml:

  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.release>17</maven.compiler.release>
    </properties>

  <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-toolchains-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>toolchain</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <toolchains>
                        <jdk>
                            <version>[${maven.compiler.release},)</version>
                        </jdk>
                    </toolchains>
                </configuration>
            </plugin>

When running mvn clean package in maven:3-eclipse-temurin-17-alpine, I get this error:

[INFO] --- maven-toolchains-plugin:3.1.0:toolchain (default) @ gitlab-maven-test --- Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar (169 kB at 2.8 MB/s) [INFO] Required toolchain: jdk [ version='[17,)' ] [ERROR] No toolchain found for type jdk [ERROR] Cannot find matching toolchain definitions for the following toolchain types: jdk [ version='[17,)' ]

Adding the following section to /usr/share/maven/conf/toolchains.xml resolved the issue:

  <toolchain>
    <type>jdk</type>
    <provides>
      <version>17.0.4.1</version>
      <vendor>Eclipse Adoptium</vendor>
    </provides>
    <configuration>
      <jdkHome>/opt/java/openjdk</jdkHome>
    </configuration>
  </toolchain>

Values are taken from mvn --version, the <vendor> element is not required, <version> could also just include the major version (17).

maffe avatar Oct 25 '22 11:10 maffe

The toolchains file can be generated using this Java code (requires Java 15 or higher):

import java.util.stream.Stream;
public class Toolchains {
    public static void main(final String[] args) {
        final String toolchains = """
            <?xml version="1.0" encoding="UTF8"?>
            <toolchains>
                <toolchain>
                   <type>jdk</type>
                   <provides>
                        <version>%s</version>
                        <vendor>%s</vendor>
                   </provides>
                   <configuration>
                        <jdkHome>%s</jdkHome>
                   </configuration>
                </toolchain>
            </toolchains>""";
        System.out.println(toolchains.formatted(Stream.of("version", "vendor", "home")
                        .map(s -> System.getProperty("java." + s))
                        .map(Toolchains::escapeXML1_0)
                        .toArray(Object[]::new)));
    }
    private static String escapeXML1_0(final String value) {
        final StringBuilder sb = new StringBuilder(value.length());
        value.codePoints().forEachOrdered(codePoint -> {
            if (codePoint == '&') {
                sb.append("&amp;");
            } else if (codePoint == '<') {
                sb.append("&lt;");
            } else if (codePoint == '>') {
                sb.append("&gt;");
            } else if (codePoint == '\'') {
                sb.append("&apos;");
            } else if (codePoint == '"') {
                sb.append("&quot;");
            } else if (codePoint == '\t' || codePoint == '\r' || codePoint == '\n'
                    || (codePoint >= 0x20 && codePoint <= 0xD7FF)
                    || (codePoint >= 0xE000 && codePoint <= 0xFFFD)
                    || (codePoint >= 0x10000 && codePoint <= 0x10FFFF)) {
                sb.appendCodePoint(codePoint);
            } else {
                sb.appendCodePoint(0xFFFD);
            }
        });
        return sb.toString();
    }
}

Save it as Toolchains.java and run java Toolchains.java > /usr/share/maven/conf/toolchains.xml

maffe avatar Nov 10 '22 21:11 maffe

This would not be required if the toolchains plugin checked if the toolchain request can be satisfied by the JDK Maven is running on.

maffe avatar Nov 16 '22 16:11 maffe

Please prioritize this issue. Toolchain support is very important, all of the core plug-ins support it and many advanced Maven projects use toolchains.