Is it possible to set up the JDK with only javac
in a reliable way, without removing and adding components until it runs (trial and error)?
In my usecase I would like to create a Linux based Docker image which contains multiple javac
versions and then use a volume to provide the source files to compile and one to retrieve the compiled class files. The container should only be able compile Java classes, nothing else.
Installing the JDK packages from the package repository of the Linux distribution and downloading ones which are not available as package manually from https://jdk.java.net/archive/ is definitely an option, but they are quite large (~ 190MB each version) and contain duplicate content and content not needed for compiling.
I have noticed that the jmods/jdk.compiler.jmod
contains javac
in the bin
folder. Extracting it and executing it failed due to missing libraries so I tried merging its contents with the modules marked as required in the module-info
:
java.base
java.compiler
However, when I then tried to run javac
I got:
Error occurred during initialization of VM
Failed setting boot class path.
Any hints in the right direction are appreciated.
In JDK versions >= 9 one can use the jlink
tool:
jlink --add-modules jdk.compiler --output my-path
This creates a custom runtime image (here in the directory my-path
) containing the needed libraries and the binary file bin/javac
. Note however that this way most of the modules which are part of java.se
(e.g. SQL, XML and Desktop classes) are not present and must be provided when invoking javac
.
The size of the runtime image can be further reduced using the following plugins:
--compress=2
: Use ZIP compression--no-header-files
: Excludes header files--no-man-pages
: Excludes man pages--strip-debug
: Strips debug information, includes the options (which can be set separately since JDK 13):
--strip-java-debug-attributes
: Strips debug information from Java class files--strip-native-debug-symbols
(Linux only, requires objcopy
): Strips debug symbols from executables and shared libraries--vm=server
: Only include server JVM(Use jlink --list-plugins
to see all available plugins)
For JDK 13 which is roughly 190 MB large, this created a folder whose contents are only 42 MB in total.