Know which command-line utilities are mandatory for distributing applications with a custom JRE.
August 14, 2020 | Download a PDF of this article
More quiz questions available here
If you have worked on our quiz questions in the past, you know none of them is easy. They model the difficult questions from certification examinations. The “intermediate” and “advanced” designations refer to the exams rather than to the questions, although in almost all cases, “advanced” questions will be harder. We write questions for the certification exams, and we intend that the same rules apply: Take words at their face value and trust that the questions are not intended to deceive you but to straightforwardly test your knowledge of the ins and outs of the language.
Imagine you are developing a modular Java 11 application from scratch and you want to distribute it with a custom Java runtime environment (JRE).
Which of the following two command-line utilities will be mandatory for accomplishing this task? Choose two.
Answer. Although many of the six tools listed in the question’s multichoice answers might be used, at the very least, two things must be done:
First, because the question mentions the application is being developed from scratch, you know there will be source code, and the source code must be compiled to create class files. This task is performed using the javac
command, which means option C is correct.
Second, it is necessary to create the distribution “bundle,” which includes the application modules along with necessary JDK modules and JRE components. This task is the job of the jlink
utility, which means option E correct.
Let’s take a closer look at the elements of this project and see what the tools actually do. Imagine you have a minimalistic application like this:
./
│ module-info.java
│
└───app
App.java
The first step is compilation, which could be something like this:
javac module-info.java app/App.java
That command would create class files laid out like this:
./
│ module-info.class
│ module-info.java
│
└───app
App.class
App.java
It’s common to have the output class files placed in a different directory tree entirely, but this example is simplified so you can focus on other things. Assume the App.java
class uses only very common Java API classes and, as a result, it depends only on the module java.base
.
package app;
public class App {
public static void main(String[] args) {
System.out.println("Hello jlink !");
}
}
And assume the application’s module name is declared as mini.mod
:
module mini.mod {
}
From there, the second step could look like this:
jlink -p . --add-modules java.base,mini.mod --output java-runtime
That command would create a custom environment in the java-runtime
directory. That environment would contain the java.base
module and your custom mini.mod
module. The directory structure (not showing the files) would look like this:
├───app
└───java-runtime
├───bin
│ ├───client
│ └───server
├───conf
│ └───security
│ └───policy
│ ├───limited
│ └───unlimited
├───include
│ └───win32
├───legal
│ └───java.base
└───lib
├───client
├───security
└───server
Option A suggests you must use the jar
utility. It’s certainly possible, and even likely that you might package your application module as a JAR file before making a custom runtime environment, but this is not a required step. The example above showed that the final package can be created using only standalone class files. From this, it’s clear option A is incorrect.
Option B suggests you must use the jmod
utility, which is used to create JMOD files. These files are similar to JAR files but cannot be used at runtime—only at compile time and link time. JMOD files typically are created to support the distribution of libraries that include platform-dependent elements. But nothing in the question indicates any requirement to use this form of packaging; therefore, option B is incorrect.
Option D suggests you must use the jdeps
utility, which is used to list the dependencies required in support of some piece of code. So, for example, jdeps
could be used to determine the modules to be included in the jlink
step, but since you already know those dependencies, jdeps
is not needed. Because that is not a mandatory step, option D is incorrect.
JIMAGE is the third archive format for the third archive packaging format for class files and other files in Java environments, along with JAR and JMOD. The jimage
utility manipulates JIMAGE format files in a manner that is broadly similar to the jar
utility. A JIMAGE file contains all the modules for the particular Java runtime whether it’s standard or a custom runtime. A JIMAGE file is created by using the jlink
utility. Because the jimage
utility is not required to build the packaged result, option F is incorrect.
Therefore, the correct options are C and E.