When I run java program, I often find myself specifying many JVM flags on the command line. As the number of those flags increases, listing all of them directly on the command line starts to become unwieldy. Therefore, I wonder if I can put those flags in a file, multiple line preferably. The most obvious choice is to use a shell script as the launcher. It works fine, but this also means that each java file is accompanied by a corresponding shell script…

In order to relieve myself of maintaining such java-shell relation for all java files, I set out to find a way to embed JVM flags directly in my java program. The following shows how this approach looks like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.io.File;
import java.io.IOException;
import java.util.*;

class Main {
static final String main_filename = "Main.java";

static int exec(String filename, List<String> jvmArgs) throws IOException,
InterruptedException {
String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
String classpath = System.getProperty("java.class.path");

List<String> command = new ArrayList<>();
command.add(javaBin);
command.addAll(jvmArgs);
command.add("-cp");
command.add(classpath);
command.add(filename);

ProcessBuilder builder = new ProcessBuilder(command);
Process process = builder.inheritIO().start();
return process.waitFor();
}

static void config_jvm(String[] jvm_args) throws Exception {
String custom_jvm_args = "custom_jvm_args";

if (System.getProperty(custom_jvm_args) == null) {
var flags = new ArrayList<>(Arrays.asList(jvm_args));
flags.add(0, "-D" + custom_jvm_args);
var ret = exec(main_filename, flags);
System.exit(ret);
}
}

public static void main(String[] args) throws Exception {
config_jvm(new String[]{
// jvm flags
"-Xms1g",
"-Xmx1g",
"-Xlog:gc",
});

// actual main body
System.out.println("hello world");
}
}

One can run it using java Main.java and all JVM flags are defined inside the java program.

PS: https://albertnetymk.github.io/2020/10/24/priority_queue/ is a concrete example where I need to control some JVM flags.