5

Does anyone know the difference between using --release and the older -source and -target command line parameters?

In the javac man page: -source Provide source compatibility with specified release -target Generate class files for specific VM version

--release Compile for a specific VM version. Supported targets: 6, 7, 8, 9, 10, 11

Could --release bind both -source and -target to the same version?

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 1
    Does this answer your question? [What is the --release flag in the Java 9 compiler?](https://stackoverflow.com/questions/43102787/what-is-the-release-flag-in-the-java-9-compiler) – Marcono1234 May 10 '20 at 20:44

3 Answers3

15

The --release flag not only sets source and target versions, but it also causes the compiler to use the symbol table for the JDK libraries corresponding to the specified release, preventing you from accidentally using APIs that are present in the compilation JDK but not present in the specified version. The --release flag was added later, and in most cases, should replace uses of --source and --target.

Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
5

I have found the answer in the Java 19 SDK source code for the java compiler:

/**
 * Handles the {@code --release} option.
 *
 * @param additionalOptions a predicate to handle additional options implied by the
 * {@code --release} option. The predicate should return true if all the additional
 * options were processed successfully.
 * @return true if successful, false otherwise
 */
public boolean handleReleaseOptions(Predicate<Iterable<String>> additionalOptions) {
    String platformString = options.get(Option.RELEASE);

    checkOptionAllowed(platformString == null,
            option -> reportDiag(Errors.ReleaseBootclasspathConflict(option)),
            Option.BOOT_CLASS_PATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND,
            Option.XBOOTCLASSPATH_PREPEND,
            Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
            Option.EXTDIRS, Option.DJAVA_EXT_DIRS,
            Option.SOURCE, Option.TARGET,
            Option.SYSTEM, Option.UPGRADE_MODULE_PATH);

    if (platformString != null) {
        PlatformDescription platformDescription =
                PlatformUtils.lookupPlatformDescription(platformString);

        if (platformDescription == null) {
            reportDiag(Errors.UnsupportedReleaseVersion(platformString));
            return false;
        }

        options.put(Option.SOURCE, platformDescription.getSourceVersion());
        options.put(Option.TARGET, platformDescription.getTargetVersion());

        context.put(PlatformDescription.class, platformDescription);

        if (!additionalOptions.test(platformDescription.getAdditionalOptions()))
            return false;

        JavaFileManager platformFM = platformDescription.getFileManager();
        DelegatingJavaFileManager.installReleaseFileManager(context,
                platformFM,
                getFileManager());
    }

    return true;
}

As the code shows, the --release option will set both source and target to the same value.

In fact, there is a check that forbids using the --release parameter if source or target have already been set.

void checkOptionAllowed(boolean allowed, ErrorReporter r, Option... opts) {
    if (!allowed) {
        Stream.of(opts)
              .filter(options :: isSet)
              .forEach(r :: report);
    }
}
tema
  • 9
  • 2
  • it will also set the --bootclasspath flag to link against the correct runtime which is sometimes forgotten with just --source and --target flags. – clinux Sep 13 '19 at 00:18
1

The --release option was added by "JEP 247: Compile for Older Platform Versions":

javac provides two command line options, -source and -target, which can be used to select the version of the Java language accepted by the compiler and the version of the class files it produces, respectively. By default, however, javac compiles against the most-recent version of the platform APIs. The compiled program can therefore accidentally use APIs only available in the current version of the platform. Such programs cannot run on older versions of the platform, regardless of the values passed to the -source and -target options.

Additionally the documentation for the --release option says:

Note: When using --release, you cannot also use the --source/-source or --target/-target options.

Marcono1234
  • 5,856
  • 1
  • 25
  • 43