Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8308399

Recommend --release when -source and -target are misused

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P4 P4
    • 22
    • 21
    • tools
    • None
    • b26

      javac is invoked with `-source` and `-target` millions of times per day. Principally this is because `<source>` and `<target>` appear in a huge number of Maven POMs. As of 5/19/23, the Maven Compiler Plugin home page says that "... the default `source` setting is 1.8 and the default `target` setting is 1.8 ... You are highly encouraged to change these defaults by setting `source` and `target` ..." (see https://maven.apache.org/plugins/maven-compiler-plugin/).

      Unfortunately, many people get confused about the meaning of `-source` (inc. `<source>`) and `-target` (inc. `<target>`), especially in the migration scenarios discussed below. javac can help by recognizing misuse and recommending `--release` instead. JEP 247 should also be more forceful in recommending `--release`, rather than merely explaining how it works. This will encourage migration to `--release` in scripts that invoke javac, and migration to `<release>` in POMs (see https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-release.html).

      Here are the two kinds of confusion over `-source` and `-target`:

      1. Confusion over `-source`

      A common scenario is developers who move from JDK 8 to JDK 17, and want to still compile their old code to target JDK 8.

      For various reasons, they think that using JDK 17 means compiling with `-source 17`, even if their codebase doesn't use language constructs newer than 2006. They inevitably try `-source 17 -target 8` and find that compilation fails (as it should) ... but that's not the end of the story. Since javac displays a *warning* -- `warning: source release 17 requires target release 17` -- they assume it's not the `-source` and `-target` options that are responsible for the compilation failure, and go down rabbit holes looking into other build components, such as the Maven compiler plugin, which they think might be causing compilation to fail.

      If javac recommended using `--release 8` when `-source >8 -target 8` is used (and said "error" rather than "warning"), then a huge number of developer-hours would be saved.

      2. Confusion over `-target`

      Another surprisingly common scenario is developers who move from JDK 8 to JDK 17, and want to migrate their old code from JDK 8 to JDK 11.

      That is, they want to compile with JDK 17's javac behaving as if it is JDK 11's javac. You might think the answer is obvious -- `-source 11 -target 11` -- but we have seen people configuring `-source 11 -target 17`. For various reasons, they think "I want the JDK 17 compiler; that means my target compiler is 17; I should set -target to 17". They are then surprised to find the output class files run only on JDK 17, and not on JDK 11.

      In addition, the "obvious" answer is wrong because it omits setting `-bootclasspath`. The right answer is simply `--release 11`.

      If javac recommended using `--release 11` when `-source 11 -target >11` is used, then a huge number of developer-hours would be saved.

            jlahoda Jan Lahoda
            abuckley Alex Buckley
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: