Javac Source and Target Options

Compile using -source and -target javac options

Compiler configuration without plugin

<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

javac -help

javac -help

-source <release> Provide source compatibility with specified release
-target <release> Generate class files for specific VM version

javac - Java programming language compiler documentation

source Specifies the version of source code accepted. The following values for release are allowed:

  • 1.6 No language changes were introduced in Java SE 6. However, encoding errors in source files are now reported as errors instead of warnings as in previous releases of Java SE.
  • 6 Synonym for 1.6.
  • 1.7 This is the default value. The compiler accepts code with features introduced in Java SE 7.
  • 7 Synonym for 1.7.

target Generate class files that target a specified version of the VM. Class files will run on the specified target and on later versions, but not on earlier versions of the VM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), and 1.7 (also 7).
The default for -target depends on the value of -source:

Compatibility

  • Java SE 7 and JDK 7 Compatibility
  • Is JDK "upward" or "backward" compatible?
  • java 7 language backwards compatibility
  • Java SE 7 Features and Enhancements
  • New features in JDK 1.6 and 1.7

Why javac target option can not be lower than source option?

Because that is how it is designed. From the documentation of javac in Java SE 15 for the --target option:

Note: The target release must be equal to or higher than the source release. (See --source.)

I guess the usual is to have old source code that you want to run in newer releases and, when starting a project, you choose your source release as the oldest release that you want to support.

Look at this answer for a discussion about backward and forward compatibility:

In brief, we can say:

  • JDK's are (usually) forward compatible.
  • JRE's are (usually) backward compatible.

You can think about it as this: JDKs can compile (usually) for newer releases and JREs can run (usually) older releases.

javac source and target options usage

The javac program knows how to handle these arguments without you providing any extra information. Do note that there is a bit of a trap here, however: these options relate to the source syntax and the class file form and content, but they do not take into account the Java standard library. As a result, they will be perfectly content to compile your code that relies on standard library classes or methods that are new in (say) Java 7, despite the source or target Java version being set to something earlier. In principle the result could run on that earlier Java version, but in practice that would require the later standard library to be backported, at least in part.

If you are developing for a particular minimum version of Java, you should develop using that version. The -source and -target options options come into play if you or someone else later wants to rebuild the source using a later javac, without dropping runtime compatibility with the earlier target Java.

Java 11: What is the difference between javac --release and -source and -target command line parameters?

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);
}
}

Ant javac difference between target and source attributes?

ANT is itself a Java program, so it uses the JAVA_HOME environment variable to choose which JVM to use at runtime.

Some ANT tasks allow you to choose a different Java compiler or JRE, over-riding the default option. For more details see the ANT documentation:

  • javac
  • java

Update

I have Java 6 and 7 installed. How do I specify ant to use Java 6 to compile?

The sources and target attributes of the javac task control compatibility settings. they do not control which JDK is used by ANT.

They enable a modern JDK to compile older versions of the Java programming language and/or produce bytecode compatible with older versions of the Java runtime.

sources is part of the standard options and targets is detailed under the cross compilation section of the javac command's documentation from Oracle:

  • http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

Finally, Oracle have produced the following document on Java compatibility:

  • http://www.oracle.com/technetwork/java/javase/compatibility-417013.html

It states that Java 6 and Java 7 are strongly compatible, which was not always the case in previous versions of Java.

PS
Apologies to repeating the same links, but hopefully the concepts are clearer?

How to compile to target Java 1.0

TL;DR javac -target 1.1 (and not using any classes or methods that were added later) will make it work on JDK >=1.0.2 (released on 1995-09-16). It's not feasible to go back more, because earlier JDKs are not publicly available to try.

The javac -target ... flag value affects the minor (byte offset 4 and and 5) and major (byte offset 6 and 7) version number stored in the .class file:

  • javac -target 1.1 in JDK 1.8 generates version 45.3, supported by JDK 1.0.2 (released on 1995-09-16), JDK 1.1.* (released in 1997-02), JDK >=1.2 (released in 1998-12). [source]
  • javac in JDK 1.0.2 (from jdk-1_0_2-win32-x86.exe, run with wine on Linux) generates version 45.3.
  • For k ≥ 2, JDK release 1.k supports class file format versions in the range 45.0 through (44+k).0 inclusive. [source]
  • javac -target 1.2 generates version 46.0, supported by JDK >=1.2.
  • javac -target 1.3 generates version 47.0, supported by JDK >=1.3.
  • javac -target 1.4 generates version 48.0, supported by JDK >=1.4.
  • etc.


Related Topics



Leave a reply



Submit