当前位置: 首页 > 知识库问答 >
问题:

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

羊舌高爽
2023-03-14

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

共有1个答案

裴兴学
2023-03-14

显然,可以使用-version运行Java命令并解析输出:

% 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

有一个内部选项并不广为人知,但在--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

如果启动一个进程被认为过于昂贵,那么可以使用读取或检测文件来代替。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"

但是,在模块化JVM中存在一些附加的文件,可以用来检测JVM是否支持模块。模块化JVM将有一个$JAVA_HOME/lib/module文件,其神奇值为0xCAFEDADAfile命令将其理解为模块文件:

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

release文件和lib/modules存在于OpenJDK和jlink生成的映像中。release文件存在于Java 8及以上版本,但lib/modules仅存在于Java 9及以上版本。

Docker的OpenJDK映像的某些版本没有release文件。其他人将Java版本安装到不同的位置,这意味着可能找不到java_home(或等价物)。如果需要100%保证在启动应用程序和查找版本的路径中使用相同版本的Java,则Java-XInternalVersion将保证工作并给出准确答案。

 类似资料:
  • 问题内容: 自从我使用Java以来​​已经有5年了,那时,每当您想分配需要清理的对象(例如套接字,DB句柄)时,都必须记住添加一个块并在其中调用cleanup方法。那里。 相比之下,在C++(或确定对象生存期的其他语言,例如Perl)中,类实现程序将定义一个析构函数,该函数在该类的对象超出范围时执行清除。这种方法的优点是对象的用户不会忘记清理它- 即使抛出异常,析构函数也会被自动调用。这种方法用R

  • 问题内容: 我注意到,Metal L&F不支持Unicode中的某些箭头字符,而Nimbus和GTK L&F则支持它们。 不支持的字符仅显示为: 我可以吗 要么(手动)查找,L&F支持哪些Unicode字符, 还是在运行时找到它? 编辑: 或者,它应该仅取决于L&F的默认字体,我的问题也许应该是: “如何找出,哪种Java字体支持哪些Unicode字符?” 问题答案: 您可以使用该方法测试对象是否

  • 问题内容: 我想知道是否有任何方法可以在Java中实现。我认为,如果没有本地对闭包的支持,这是不可能的。 问题答案: Java 8(2014年3月18日发布)不支持curring。可以将Missingfaktor在答案中发布的示例Java代码重写为: …这是非常好的。就个人而言,有了Java 8,我几乎没有理由使用替代的JVM语言(例如Scala或Clojure)。当然,它们提供了其他语言功能,但

  • 从python语言的API文档中,我找不到任何关于graph x的东西,这是否意味着它还不支持,如果现在不支持,它会支持吗?

  • 我的Android应用程序已经有了一个运行正常的Exoplayer实现,我需要知道Exoplayer是否支持在HDCP中播放短跑视频(以及它是如何工作的)。演示应用程序有一些具有“HDCP功能”的示例,但我在代码库中找不到任何与它如何处理这一问题有关的内容(DASH manifest文件本身是否指定了HDCP功能?)。

  • 问题内容: 我正在尝试从C#程序集(使用)动态运行.jar 。现在,可以从控制台应用程序运行: 但是,在一个程序集中,我不断收到“系统找不到指定的文件”的信息,必须将行更改为Java的完整路径,如下所示: 这显然不会。我需要一种动态(但声明式)确定Java安装位置的方法。 我开始考虑查找注册表,但是到那里时,我注意到版本有特定的键,甚至不能保证它们是数字的(例如“ HKEY_LOCAL_MACHI