代码之家  ›  专栏  ›  技术社区  ›  AlBlue RACGAMERUP

我如何确定安装的Java是否支持模块?

  •  0
  • AlBlue RACGAMERUP  · 技术社区  · 3 年前

    如果我有一个启动器脚本,我如何确定JVM是否支持模块(例如9+)来决定是否使用 -classpath --module 脚本?

    1 回复  |  直到 3 年前
        1
  •  5
  •   AlBlue RACGAMERUP    3 年前

    方法

    有几种方法可以找到信息。可以解析确切的Java版本,或者查找仅在模块化JVM或非模块化JVM中发现的差异。

    运行java-版本

    显然,有可能运行 java 命令与a -version 并解析输出:

    % java -version
    openjdk version "11.0.10" 2021-01-19 LTS
    OpenJDK Runtime Environment Zulu11.45+27-CA (build 11.0.10+9-LTS)
    OpenJDK 64-Bit Server VM Zulu11.45+27-CA (build 11.0.10+9-LTS, mixed mode)
    

    然而,这涉及启动一个进程,运行许多设置/初始化选项,以及验证/检验其他标志。这意味着,虽然很快,但不会是瞬间的:

    % time java -version
    0.08s user 0.02s system 101% cpu 0.100 total
    

    运行java-Xinternalveversion

    有一个内部选项并不广为人知,但记录在 -java -X 标志,它不实例化Java类,只是返回二进制文件的状态:

    -Xinternalversion
        displays more detailed JVM version information than the
        -version option
    

    此启动速度比上述稍快:

    % time java -Xinternalversion
    OpenJDK 64-Bit Server VM (11.0.10+9-LTS) for bsd-amd64 JRE (Zulu11.45+27-CA) (11.0.10+9-LTS),
    built on Dec 30 2020 12:39:54 by "zulu_re" with gcc 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)
    0.01s user 0.01s system 88% cpu 0.029 total
    

    这也适用于OpenJ9图像:

    % java -Xinternalversion
    Eclipse OpenJ9 OpenJDK 64-bit Server VM (11.0.10+9) from linux-amd64 JRE
    with Extensions for OpenJDK for Eclipse OpenJ9 11.0.10.0,
    built on Jan 20 2021 08:58:22 by  with g++-7.5 (GCC) 7.5.0
    

    正在读取JAVA_HOME/release文件

    如果启动一个进程被认为太昂贵,那么可以使用读取或检测文件来代替。OpenJDK派生的JVM具有 release 文件,其中包含有关Java版本的信息:

    % grep VERSION $JAVA_HOME/release
    IMPLEMENTOR_VERSION="Zulu11.45+27-CA"
    JAVA_VERSION="11.0.10"
    JAVA_VERSION_DATE="2021-01-19"
    
    % grep VERSION $JAVA_8_HOME/release
    JAVA_VERSION="1.8.0_282"
    OS_VERSION="11.2"
    

    正在读取JAVA_HOME/lib/modules文件

    模块化JVM中存在其他文件(作为 JEP 220 重构),其可用于检测JVM是否支持模块。模块化JVM将具有 $JAVA_HOME/lib/modules 具有魔术值的文件 0xcafedada ,这是可以理解的 file 命令作为模块文件:

    % file $JAVA_HOME/lib/modules 
    /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/lib/modules: Java module image (little endian), version 1.0
    

    这个 释放 文件和 lib/modules 存在于OpenJDK和由生成的映像中 jlink The 释放 文件存在于Java 8及更高版本上,但 lib/模块 仅在Java 9及更高版本上存在。

    某些版本 Docker's OpenJDK image 没有 释放 文件。其他人将Java版本安装到不同的位置,这意味着 JAVA_HOME (或同等)可能找不到。如果要求100%保证相同版本的 Java 在启动应用程序以及查找版本的路径中使用, java -Xinternalversion 保证有效并给出准确答案。

    正在查找rt.jar/classes.zip

    测试预模块化JVM存在的另一种方法是查看是否 rt.jar (或者对于非常旧的JVM, classes.zip )存在于 JAVA_HOME/jre/lib 。在Java 9及更高版本中缺少这些文件。

    摘要

    如果你已经有了 JAVA_HOME ,那么最快的方法就是确定 JAVA_HOME/lib/modules 文件。为了正确,你可以验证这个神奇的数字 0x卡费达达 (小端序或大端序)。但是,此文件在Java 8或更低版本上不存在,但在Java 9及更高版本上存在,包括 jlink 生成的图像。

    数据

    从各种平台收集的数据:

    openjdk docker镜像

    又称作 mystery meat '图片)来自 https://hub.docker.com/_/openjdk/

    for i in {7..15}
    do
      echo
      echo openjdk:$i
      docker run --rm -it openjdk:$i sh -c '
        ls -l $(dirname $(readlink -f $(command -v java)))/../lib/modules
        grep JAVA_VERSION= $(dirname $(readlink -f $(command -v java)))/../release 
        java -Xinternalversion'
    done
    
    openjdk:7
    ls: cannot access /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/../lib/modules: No such file or directory
    grep: /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/../release: No such file or directory
    OpenJDK 64-Bit Server VM (24.221-b02) for linux-amd64 JRE (1.7.0_221-b02), built on May  9 2019 19:23:05 by "pbuilder" with gcc 4.9.2
    
    openjdk:8
    ls: cannot access '/usr/local/openjdk-8/bin/../lib/modules': No such file or directory
    JAVA_VERSION="1.8.0_282"
    OpenJDK 64-Bit Server VM (25.282-b08) for linux-amd64 JRE (1.8.0_282-b08), built on Jan 11 2021 02:10:15 by "openjdk" with gcc 4.4.7 20120313 (Red Hat 4.4.7-23)
    
    openjdk:9
    -rw-r--r-- 1 root root 157113207 Apr  2  2018 /usr/lib/jvm/java-9-openjdk-amd64/bin/../lib/modules
    grep: /usr/lib/jvm/java-9-openjdk-amd64/bin/../release: No such file or directory
    OpenJDK 64-Bit Server VM (9.0.4+12-Debian-4) for linux-amd64 JRE (9.0.4+12-Debian-4), built on Apr  2 2018 07:28:15 by "buildd" with gcc 7.3.0
    
    openjdk:10
    -rw-r--r-- 1 root root 156084936 Oct 21  2018 /usr/lib/jvm/java-10-openjdk-amd64/bin/../lib/modules
    grep: /usr/lib/jvm/java-10-openjdk-amd64/bin/../release: No such file or directory
    OpenJDK 64-Bit Server VM (10.0.2+13-Debian-2) for linux-amd64 JRE (10.0.2+13-Debian-2), built on Oct 21 2018 10:11:46 by "buildd" with gcc 8.2.0
    
    openjdk:11
    -rw-rw-r-- 1 root root 142005674 Jan 12 10:31 /usr/local/openjdk-11/bin/../lib/modules
    JAVA_VERSION="11.0.10"
    OpenJDK 64-Bit Server VM (11.0.10+9) for linux-amd64 JRE (11.0.10+9), built on Jan 12 2021 05:23:33 by "openjdk" with gcc 4.4.7 20120313 (Red Hat 4.4.7-23)
    
    openjdk:12
    -rw-r--r-- 1 668 668 138934817 Jul 16  2019 /usr/java/openjdk-12/bin/../lib/modules
    JAVA_VERSION="12.0.2"
    OpenJDK 64-Bit Server VM (12.0.2+10) for linux-amd64 JRE (12.0.2+10), built on Jul 16 2019 00:57:08 by "mach5one" with gcc 7.3.0
    
    openjdk:13
    -rw-r--r-- 1 10668 10668 140052206 Dec 11  2019 /usr/java/openjdk-13/bin/../lib/modules
    JAVA_VERSION="13.0.2"
    OpenJDK 64-Bit Server VM (13.0.2+8) for linux-amd64 JRE (13.0.2+8), built on Dec 11 2019 09:23:26 by "mach5one" with gcc 8.2.0
    
    openjdk:14
    -rw-r--r-- 1 root root 143828463 Jul  8  2020 /usr/java/openjdk-14/bin/../lib/modules
    JAVA_VERSION="14.0.2"
    OpenJDK 64-Bit Server VM (14.0.2+12-46) for linux-amd64 JRE (14.0.2+12-46), built on Jul  8 2020 23:30:21 by "mach5one" with gcc 8.3.0
    
    openjdk:15
    -rw-r--r-- 1 root root 137265245 Dec  7 20:09 /usr/java/openjdk-15/bin/../lib/modules
    JAVA_VERSION="15.0.2"
    OpenJDK 64-Bit Server VM (15.0.2+7-27) for linux-amd64 JRE (15.0.2+7-27), built on Dec  7 2020 19:54:59 by "mach5one" with gcc 9.2.0
    

    采用OpenJDK热点映像

    https://hub.docker.com/_/adoptopenjdk

    for i in 8 {11..15}
    do
      echo
      echo adoptopenjdk:$i-hotspot
      docker run --rm -it adoptopenjdk:$i-hotspot sh -c '
        ls -l $(dirname $(readlink -f $(command -v java)))/../lib/modules
        grep JAVA_VERSION= $(dirname $(readlink -f $(command -v java)))/../release
        java -Xinternalversion'
    done
    
    adoptopenjdk:8-hotspot
    ls: cannot access '/opt/java/openjdk/bin/../lib/modules': No such file or directory
    JAVA_VERSION="1.8.0_282"
    OpenJDK 64-Bit Server VM (25.282-b08) for linux-amd64 JRE (1.8.0_282-b08), built on Jan 20 2021 11:56:52 by "jenkins" with gcc 7.5.0
    
    adoptopenjdk:11-hotspot
    -rw-r--r-- 1 root root 142006963 Jan 20 12:17 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="11.0.10"
    OpenJDK 64-Bit Server VM (11.0.10+9) for linux-amd64 JRE (11.0.10+9), built on Jan 20 2021 12:11:51 by "" with gcc 7.5.0
    
    adoptopenjdk:12-hotspot
    -rw-r--r-- 1 500 500 141885840 Jul 18  2019 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="12.0.2"
    OpenJDK 64-Bit Server VM (12.0.2+10) for linux-amd64 JRE (12.0.2+10), built on Jul 18 2019 14:41:47 by "jenkins" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)
    
    adoptopenjdk:13-hotspot
    -rw-r--r-- 1 root root 143013610 Jan 17  2020 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="13.0.2"
    OpenJDK 64-Bit Server VM (13.0.2+8) for linux-amd64 JRE (13.0.2+8), built on Jan 17 2020 15:30:29 by "jenkins" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)
    
    adoptopenjdk:14-hotspot
    -rw-r--r-- 1 root root 155307303 Jul 15  2020 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="14.0.2"
    OpenJDK 64-Bit Server VM (14.0.2+12) for linux-amd64 JRE (14.0.2+12), built on Jul 15 2020 09:06:52 by "" with gcc 7.5.0
    
    adoptopenjdk:15-hotspot
    -rw-r--r-- 1 root root 147653756 Jan 21 12:09 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="15.0.2"
    OpenJDK 64-Bit Server VM (15.0.2+7) for linux-amd64 JRE (15.0.2+7), built on Jan 21 2021 11:55:36 by "" with gcc 7.5.0
    

    采用OpenJDK OpenJ9镜像

    https://hub.docker.com/_/adoptopenjdk 使用-openj9口味

    for i in 8 {11..15}
    do
      echo
      echo adoptopenjdk:$i-openj9 
      docker run --rm -it adoptopenjdk:$i-openj9 sh -c ' 
        ls -l $(dirname $(readlink -f $(command -v java)))/../lib/modules
        grep JAVA_VERSION= $(dirname $(readlink -f $(command -v java)))/../release
        java -Xinternalversion'
    done
    
    adoptopenjdk:8-openj9
    ls: cannot access '/opt/java/openjdk/bin/../lib/modules': No such file or directory
    JAVA_VERSION="1.8.0_282"
    Eclipse OpenJ9 OpenJDK 64-bit Server VM (1.8.0_282-b08) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 8.0.282.0, built on Jan 20 2021 08:35:35 by  with g++-7.5 (GCC) 7.5.0
    
    adoptopenjdk:11-openj9
    -rw-r--r-- 1 root root 124147727 Jan 20 09:22 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="11.0.10"
    Eclipse OpenJ9 OpenJDK 64-bit Server VM (11.0.10+9) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 11.0.10.0, built on Jan 20 2021 08:58:22 by  with g++-7.5 (GCC) 7.5.0
    
    adoptopenjdk:12-openj9
    -rw-r--r-- 1 500 500 125220100 Jul 19  2019 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="12.0.2"
    Eclipse OpenJ9 OpenJDK 64-bit Server VM (12.0.2+10) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 12.0.2.0, built on Jul 19 2019 19:53:58 by jenkins with g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
    
    adoptopenjdk:13-openj9
    -rw-r--r-- 1 root root 124722695 Jan 17  2020 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="13.0.2"
    Eclipse OpenJ9 OpenJDK 64-bit Server VM (13.0.2+8) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 13.0.2.0, built on Jan 17 2020 10:38:21 by jenkins with g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
    
    adoptopenjdk:14-openj9
    -rw-r--r-- 1 root root 128237302 Jul 15  2020 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="14.0.2"
    Eclipse OpenJ9 OpenJDK 64-bit Server VM (14.0.2+12) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 14.0.2.0, built on Jul 15 2020 14:33:14 by  with g++-7.5 (GCC) 7.5.0
    
    adoptopenjdk:15-openj9
    -rw-r--r-- 1 root root 122382952 Jan 21 08:41 /opt/java/openjdk/bin/../lib/modules
    JAVA_VERSION="15.0.2"
    Eclipse OpenJ9 OpenJDK 64-bit Server VM (15.0.2+7) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 15.0.2.0, built on Jan 21 2021 08:12:28 by  with g++-7.5 (GCC) 7.5.0
    

    Azul Zulu图片

    https://hub.docker.com/r/azul/zulu-openjdk

    for i in 7 8 {11..15}
    do
      echo
      echo azul/zulu-openjdk:$i
      docker run --rm -it azul/zulu-openjdk:$i sh -c '       
        ls -l $(dirname $(readlink -f $(command -v java)))/../lib/modules
        grep JAVA_VERSION= $(dirname $(readlink -f $(command -v java)))/../release
        java -Xinternalversion'
    done
    
    azul/zulu-openjdk:7
    ls: cannot access '/usr/lib/jvm/zulu7-ca-amd64/jre/bin/../lib/modules': No such file or directory
    grep: /usr/lib/jvm/zulu7-ca-amd64/jre/bin/../release: No such file or directory
    OpenJDK 64-Bit Server VM (24.292-b07) for linux-amd64 JRE (Zulu 7.44.0.11-CA-linux64) (1.7.0_292-b07), built on Dec 25 2020 02:30:15 by "zulu_re" with gcc 4.4.7 20120313 (Red Hat 4.4.7-3)
    
    azul/zulu-openjdk:8
    ls: cannot access '/usr/lib/jvm/zulu8-ca-amd64/jre/bin/../lib/modules': No such file or directory
    grep: /usr/lib/jvm/zulu8-ca-amd64/jre/bin/../release: No such file or directory
    OpenJDK 64-Bit Server VM (25.282-b08) for linux-amd64 JRE (Zulu 8.52.0.23-CA-linux64) (1.8.0_282-b08), built on Jan 12 2021 07:57:43 by "zulu_re" with gcc 4.4.7 20120313 (Red Hat 4.4.7-3)
    
    azul/zulu-openjdk:11
    -rw-r--r-- 1 root root 144713046 Jan 13 21:49 /usr/lib/jvm/zulu11-ca-amd64/bin/../lib/modules
    JAVA_VERSION="11.0.10"
    OpenJDK 64-Bit Server VM (11.0.10+9-LTS) for linux-amd64 JRE (Zulu11.45+27-CA) (11.0.10+9-LTS), built on Dec 30 2020 23:45:15 by "zulu_re" with gcc 4.9.2 20150212 (Red Hat 4.9.2-6)
    
    azul/zulu-openjdk:12
    -rw-r--r-- 1 root root 141878585 Jul 11  2019 /usr/lib/jvm/zulu-12-amd64/bin/../lib/modules
    JAVA_VERSION="12.0.2"
    OpenJDK 64-Bit Server VM (12.0.2+3) for linux-amd64 JRE (Zulu12.3+11-CA) (12.0.2+3), built on Jul 11 2019 18:01:29 by "zulu_re" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)
    
    azul/zulu-openjdk:13
    -rw-r--r-- 1 root root 143053558 Jan 13 21:37 /usr/lib/jvm/zulu13-ca-amd64/bin/../lib/modules
    JAVA_VERSION="13.0.6"
    OpenJDK 64-Bit Server VM (13.0.6+5-MTS) for linux-amd64 JRE (13.0.6+5-MTS) (Zulu13.37+21-CA), built on Dec 26 2020 00:17:26 by "zulu_re" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)
    
    azul/zulu-openjdk:14
    -rw-r--r-- 1 root root 146757927 Jul 10  2020 /usr/lib/jvm/zulu-14-amd64/bin/../lib/modules
    JAVA_VERSION="14.0.2"
    OpenJDK 64-Bit Server VM (14.0.2+12) for linux-amd64 JRE (14.0.2+12) (Zulu14.29+23-CA), built on Jul 10 2020 22:15:57 by "zulu_re" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)
    
    azul/zulu-openjdk:15
    -rw-r--r-- 1 root root 140186164 Jan 22 17:19 /usr/lib/jvm/zulu15-ca-amd64/bin/../lib/modules
    JAVA_VERSION="15.0.2"
    OpenJDK 64-Bit Server VM (15.0.2+7) for linux-amd64 JRE (15.0.2+7) (Zulu15.29+15-CA), built on Jan 21 2021 06:01:59 by "zulu_re" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)