1

I am upgrading my Maven-built, Java 8 app to Java 11. In my POM I specify:

<properties>
  <java.version>1.11</java.version>
  <maven.compiler.source>${java.version}</maven.compiler.source>
  <maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

When I go to build my app using my normal Maven build invocation:

mvn verify -Plocal -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"

I get:

[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< example.com:myapp-svc >------------------------
[INFO] Building myapp-svc 1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-checkstyle-plugin:3.1.2:check (validate) @ myapp-svc ---
[WARNING] Old version of checkstyle detected. Consider updating to >= v8.30
[WARNING] For more information see: https://maven.apache.org/plugins/maven-checkstyle-plugin/examples/upgrading-checkstyle.html
[INFO] Starting audit...
Audit done.
[INFO] You have 0 Checkstyle violations.
[INFO] 
[INFO] --- jacoco-maven-plugin:0.8.7:prepare-agent (default) @ myapp-svc ---
[INFO] argLine set to -javaagent:/Users/myuser/.m2/repository/org/jacoco/org.jacoco.agent/0.8.7/org.jacoco.agent-0.8.7-runtime.jar=destfile=/Users/myuser/workspace/myapp-svc/target/jacoco.exec
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ myapp-svc ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 6 resources
[INFO] Copying 154 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ myapp-svc ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 456 source files to /Users/myuser/workspace/myapp-svc/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.076 s
[INFO] Finished at: 2021-11-12T12:52:52-05:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project myapp-svc: Fatal error compiling: error: invalid target release: 1.11 -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

So it looks like the maven-compiler-plugin:3.8.1 plugin is incompatible with Java 11. The thing is, I don't directly specify that plugin anywhere in my POM. So something, somewhere is pulling it and using it, and my guess is that I have to update whatever that thing is so that it pulls in a version of the maven-compiler-plugin that is compatible with Java 11.

So how can I tell what's pulling it in and using it? Or if thats not what's happening, what is and how do I fix it?

hotmeatballsoup
  • 385
  • 6
  • 58
  • 136
  • 3
    Drop the “1.” from Java version. Change to: `11` – Basil Bourque Nov 12 '21 at 18:07
  • Oh wow, thanks @BasilBourque (+1). This works, however I'm curious, previously that value was `1.8`. So why _wouldn't_ it be 1.11 for Java 11? Also in the spirit of "teach a man to fish", how did you know that the proper value for this was "11" and not "1.11"? Thanks again! – hotmeatballsoup Nov 12 '21 at 18:17
  • You’ll likely find the change in Java version numbering documented and explained in a [Java JEP](https://openjdk.java.net/jeps/0). – Basil Bourque Nov 12 '21 at 18:25
  • Please post and accept an Answer to your Question explaining exactly what you did to resolve the issue. And link to that JEP, if you find it. – Basil Bourque Nov 12 '21 at 18:27
  • Is that link where you found the answer (11 instead of 1.11)? Not seeing anything in there that jumps out as being obvious. I will do as you request and post an answer but only once I understand where this information can be specifically found, so that it is helpful for others in the future, and with other Java versions besides 11. In my particular case, I got lucky and had you to spoonfeed the answer to me, but others in the future may not be so lucky! If we can find where this knowledge of yours came from, specifically, I'll happily provide an answer that spells this all out. Thanks again! – hotmeatballsoup Nov 12 '21 at 18:30
  • 1
    As you are quite interested, you should have but a bit more effort into perusing the Java JEPs as I had suggested. Simply searching for the word "version" in the JEP titles would have brought you to [*JEP 223: New Version-String Scheme*](https://openjdk.java.net/jeps/223). You can learn many wonderful things about Java by studying the JEPs, such as [records](https://openjdk.java.net/jeps/395). – Basil Bourque Nov 12 '21 at 22:25

2 Answers2

3

tl;dr

Drop the 1. prefix.

<java.version>11</java.version>

Details

New versioning scheme in Java 9+

As of Java 9 and later, the Java version numbering scheme was altered to drop the never-changing 1.*.

For official documentation and explanation, see JEP 223: New Version-String Scheme, section Dropping the initial 1 element from version numbers.

To quote JEP 223:

This proposal drops the initial 1 element from JDK version numbers. That is, it suggests that the first release of JDK 9 will have the version number 9.0.0 rather than 1.9.0.0.

After nearly twenty years it's clear that the second element of the current version-number scheme is the JDK's de facto $MAJOR version number.

Therefore your POM should use:

<java.version>11</java.version>

<maven.compiler.release>

By the way, if you update the other parts of your POM related to the compiler, building, and testing to their latest versions, you can replace the pair of elements <maven.compiler.source> and <maven.compiler.target> to simply this one element: <maven.compiler.release>.

So your snippet:

<properties>
  <java.version>1.11</java.version>
  <maven.compiler.source>${java.version}</maven.compiler.source>
  <maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

… becomes this:

<properties>
  <java.version>11</java.version>
  <maven.compiler.release>${java.version}</maven.compiler.release>
</properties>

And in my own work, I do not even have a java.version element at all. I use simply this snippet, to specify UTF-8 as the charactering encoding, and Java 17 as the compiling and building version.

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

With UTF-8 becoming the new Java 18 default across platforms (see JEP 400: UTF-8 by Default), in the future I may be able to drop that first element, <project.build.sourceEncoding>.

  <properties>
      <maven.compiler.release>17</maven.compiler.release>
  </properties>

Here is my modified version of the Apache Maven Quickstart Archetype, as a full example.

<?xml version="1.0" encoding="UTF-8"?>

<!-- Modified by Basil Bourque as of 2021-11 to use the latest versions. -->
<project xmlns = "http://maven.apache.org/POM/4.0.0"
         xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>work.basil.example</groupId>
    <artifactId>Quickie</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>Quickie</name>
    <url>http://www.basil.work</url>

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

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.1</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.2.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>3.0.0-M5</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.2.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>3.0.0-M1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>3.0.0-M1</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.9.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.1.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
2

Replace <java.version>1.11</java.version> by <java.version>11</java.version>

Deepanshu Rathi
  • 381
  • 1
  • 10
  • Thanks @Deepanshu (+1), but how did you know this? Is it published in the Maven tooling docs somewhere? – hotmeatballsoup Nov 12 '21 at 18:30
  • Because from java 6 or 5 onwards they dropped the "1." from versions, There's no such thing as java 1.11, Please mark as accepted if it accurately answered your question – Deepanshu Rathi Nov 12 '21 at 18:33
  • The problem is that `1.8` works perfectly fine for specifying Java 8. Although your answer does work, and I do want to accept it, I'd really prefer some type of citation either from Oracle or Maven (or some authority!) that explains why 1.8 is valid but 1.11 is not! Thanks again for all your help! – hotmeatballsoup Nov 12 '21 at 18:36
  • In other words @Deepanshu, how did you know `11` was the answer? I'm sure it did not just come to you in a vision (!!!) so wherever you looked for that answer is likely the proper source we need cited here. – hotmeatballsoup Nov 12 '21 at 18:44
  • Read this section 'Dropping the initial 1 element from version numbers' from https://openjdk.java.net/jeps/223 Also take a look at https://stackoverflow.com/questions/54467287/how-to-specify-java-11-version-in-spring-spring-boot-pom-xml – Deepanshu Rathi Nov 12 '21 at 18:45
  • Haha @hotmeatballsoup I started coding from java 11 only, so never had to use "1." versions. I hope I have done the citing part – Deepanshu Rathi Nov 12 '21 at 18:47