David P. Caldwell
David P. Caldwell

Reputation: 3829

Robust and performant way to detect whether a JDK has the module system given its filesystem path?

I have a script that launches a Java program, and allows the user to specify the path of the Java installation to use via an environment variable.

I'd like that script to supply Java module system arguments (specifically --add-opens) when the target JDK has the module system (JPMS, or "Jigsaw"), and omit them when it does not (if they are not omitted, the startup will fail, as JDK 8 complains about the unrecognized arguments). Right now it omits them, which results in undesirable warnings on JDK 9+ (and yes, I am looking into fixing the root causes as well).

I can implement this. Probably the most robust way would be to first invoke a Java program in the underlying script that detected the module system and emitted its results to standard output (or process exit status, maybe); the calling script could then examine that output to know whether the underlying JDK was JPMS-enabled.

I could also parse java -version but I'm not sure what's guaranteed about the format of that string.

I am hoping there's a way that's (1) robust, and (2) performant -- maybe checking for the existence of a particular file in the installation, or scanning a particular JAR file from within the calling script, or something.

Anyone expert on JPMS have a heuristic that is robust and performant for this?

Upvotes: 0

Views: 70

Answers (2)

Mark Reinhold
Mark Reinhold

Reputation: 5205

Every version of Java since and including 9 contains the module system.

Every OpenJDK-derived implementation of Java 9 and later, which includes Oracle’s commercial JDK builds, supports the --version option; earlier versions only support the -version (single dash) option. So a quick and dirty way to check for 9 and later would be if $JAVA_HOME/bin/java --version >&/dev/null; then ....

Upvotes: 2

Abra
Abra

Reputation: 20914

The java class file format is the same for all java versions and contains the version number. Just read the header bytes of one of the relevant .class files.

For example, the last line of the output from the below PowerShell command is the version number.

Get-Content -Path "Key.class" -TotalCount 8 -Encoding Byte

The output is

202
254
186
190
0
0
0
52

52 is the version number which means file Key.class was compiled with JDK 8.

Upvotes: 0

Related Questions