Week 133 — How can one use a newer JDK to compile applications for an older Java version?

Question of the Week #133
How can one use a newer JDK to compile applications for an older Java version?
5 Replies
Emmy
Emmy2mo ago
Java allows running application compiled for an older Java version using a newer JDK like any other application. If code is compiled with JDK 8, it can typically still be used with JDK 21 (unless it uses internal APIs that have been change or removed) without any modifications. Similarly, it is possible to use a newer JDK to compile applications for older JDKs. To do this, the classes to compile must not use any language or features that were introduced after the Java version to compile to. If that's the case, the --release option followed by the Java version to compile to can be added to the javac command. For example, to use a JDK 21 installation to compile an application for JDK 17, the command javac --release 17 YourClass.java (or similar) can be used. The class can then be used with JDK 17 or later. Another option is the use of --source and --target instead of --release. The --source argument specifies the language level for the Java classes to compile while the --target option specifies the version of the class files to compile to (i.e. the compiled classes can be used with these JDK versions or newer). If thse options are present, the --source argument must refer to a lower Java version than --target. While --release checks which parts of the JDK standard libraries are used and only allows using what was available in the Java version to compile to. This is not done with --source/--target which allows using API features not present in the version to compile to. This can result in the compiled types being unusable with the specified version. For this reason, --release should typically be preferred over --source/--target
📖 Sample answer from dan1st
Emmy
Emmy2mo ago
The Java compiler, javac, provides 3 flags that can control the supported language level of the source along with the generated bytecode level of the compiled class files: - --source - Tells the compiler to allow Java syntax up to the specified version. In JDK versions prior to 13, the flag was -source; more recent versions still support this flag for backwards compatibility. - --target - Tells the compiler to generate bytecode that is compatible with the specified JVM version. In JDK versions prior to 13, the flag was -target; more recent versions still support this flag for backwards compatibility. - --release - Introduced in JDK 9, this flag combines the functionality of --source & --target, but it also does more. It ensures that the code only uses Java Platform APIs that are present in the specified release. This addresses a bug where code compiled with an older --source/--target specification may still not run on the older JRE. This flag cannot be used in conjunction with --source or --target.
Submission from dangerously_casual
Emmy
Emmy2mo ago
There are situations where you need to ensure your code runs on older Java versions while using a newer JDK for development. This is called cross-compilation, and java provides compiler options to achieve this backward compatibility. Modern (JDK 9+) (Recommended) Use of --release flag is recommended for JDK 9+, javac --release 8 MyClass.java. --release flag ensures full compability by compiling against the specified target's standard libraries. It replaces the combination of the three legacy flags, -target -source -boothclasspath, but is more stricter and easy to use. Legacy (before JDK 9) Compilation Flags: - -target: This specifies the target Java version for the compiled bytecode, javac -target 8 MyClass.java. - -source: This tells the compiler which version of Java source code you're using, javac -source 8 -target 8 MyClass.java - -bootclasspath: This overrides the default Java standard library used by javac during compilation. javac -source 8 -target 8 -bootclasspath /path/to/java8/rt.jar MyClass.java. Notes: - You cannot set a -source version higher than the -target version. - Without -bootclasspath, you may accidentally use newer APIs that don’t exist in the target JDK, which compiles fine but crashes at runtime.
⭐ Submission from daysling
Emmy
Emmy2mo ago
javac --release x or javac --source x --target x
Submission from fakl
Emmy
Emmy2mo ago
javac --release 8 -d out MyApp.java
Submission from karlas1.

Did you find this page helpful?