【问题标题】:JDK 9 + Mac OS + jlink?JDK 9 + Mac OS + jlink?
【发布时间】:2018-03-06 20:00:44
【问题描述】:

我在 Mac OS 上安装了 JDK 9 的发行版。

jshell 很好用,Jigsaw 模块支持很好,但是没有 jlink:

➜  java --version
java 9
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

这是空的:

find /System/Library/Frameworks/JavaVM.framework/Versions/Current/ -iname jlink\*

仅供参考:

➜  ls -l $(which java)
lrwxr-xr-x  1 root  wheel  74 Nov  7  2016 /usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java

【问题讨论】:

    标签: java macos java-9 java-platform-module-system jlink


    【解决方案1】:

    您可以使用which java 验证您的JAVA_HOME,并确保它指向默认安装路径,理想情况下应该是

    /Library/Java/JavaVirtualMachines...
    

    [例如我用它作为export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/] 进一步您可以在 Contents 的 bin 文件夹中找到jlink

    find /Library/Java/JavaVirtualMachines/jdk-9.jdk -iname jlink\* 
    

    应该返回

    /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin
    

    附上屏幕截图以供参考其安装位置:-

    注意:虽然在屏幕截图中,该命令并未成功运行,但已被识别。

    【讨论】:

    • 安装在/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/jlink,谢谢!当计时器允许我接受这个答案时,我会接受。但是,which java 表示完全不同的目录,因为我更新了我的主要帖子以显示。我不认为这是自定义更改,我认为这是默认更改。
    • @clay ya 可能会尝试更新 bash_profile 以导出更新的JAVA_HOME,这也可能修复which java
    【解决方案2】:

    要将 JDK 9 工具添加到您的路径,请将以下内容添加到您的主目录的文件 .bashrc

    export JAVA_HOME=$(/usr/libexec/java_home -v 9)
    export PATH="$JAVA_HOME/bin:$PATH"
    

    你注意到-v 9了吗?如果您想切换回 JDK 1.8,可以将其更改为 1.8。对于在 Finder 中找不到 .bashrc 的任何新手:按⌘⇧。 (command shift dot) 显示隐藏文件。

    【讨论】:

      【解决方案3】:

      这里有一些重要的上下文:Understanding Oracle's Java on Mac

      标准的 JDK 实用程序(java、javac 等)实际上安装在 /Library/Java/JavaVirtualMachines/(JDK_VERSION)/Contents/Home/bin

      /usr/bin 在路径中,在该目录中您会找到所有常用的 JDK 实用程序。当您键入java(或任何其他命令)时,它会找到那些,但它们实际上是指向/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands 中具有相同名称的可执行文件的符号链接。这些可执行文件只是询问您的 JAVA_HOME 环境变量(应该指向实际安装位​​置)并调用在那里找到的真实二进制文件的包装器。我不清楚为什么有人认为这两层抽象是必要的,但事实就是如此。

      在 Java 9 发布后的某个时候,jshell 的符号链接和包装器被添加到 macOS,但似乎没有为 jlink 做这样的事情。

      为了让事情持续向前发展,我建议编写一个等效的包装器,将它放在正确的位置,并在/usr/bin 中添加一个符号链接。

      不幸的是,由于包装脚本位于/System 下,因此在禁用系统完整性保护之前,您无法创建或修改任何内容,即使是根用户也是如此。这需要几分钟并需要重新启动几次,但很容易做到:

      1. 重新启动您的计算机。重新启动时,按住 R。这将导致机器以恢复模式启动。当您看到进度条时,您可以松开按键。
      2. 进入恢复模式后,从实用程序菜单中选择终端。
      3. 在提示符下,键入csr disable。系统将提示您重新启动以使更改发生。也这样做。
      4. 回到常规模式后,打开终端并执行以下操作:

        % sudo vi /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jlink
        Password:
        
      5. 在提示符处输入您的密码。

      6. vi中,按I切换到插入模式,然后输入以下文本:

        #!/bin/bash
        $JAVA_HOME/bin/jlink $@
        
      7. 然后按esc退出插入模式,输入保存退出:wq.

      8. 发出以下命令以使脚本可执行、创建符号链接、使符号链接可执行并检查您的工作:

        % sudo chmod +x /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jlink
        % sudo ln -s /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jlink /usr/bin/jlink
        % sudo chmod +x /usr/bin/jlink
        % ls -la $(which jlink)
        lrwxr-xr-x  1 root  wheel    75B Jun 19 10:33 /usr/bin/jlink@ -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jlink
        % ls -la $(which java) 
        lrwxr-xr-x  1 root  wheel    74B Sep 25  2017 /usr/bin/java@ -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
        % jlink --version
        10.0.1
        % 
        
      9. 现在是时候重新启用系统完整性保护了。重新启动进入恢复模式(步骤 1 中的说明)。

      10. 进入恢复模式后,从实用程序菜单中选择终端。
      11. 在提示符下,键入csr enable。系统将再次提示您重新启动。

      如果您不想禁用/重新启用 SIP,您可以在 /usr/bin/jlink 创建脚本。

      希望未来的 macOS 版本会默认包含这些。

      【讨论】:

      • 只是一个后续说明:我认为我可以优化这些步骤,以便您只需进入恢复模式一次,并在您在那里时创建必要的文件。不幸的是,该磁盘不会被挂载。如果您对这些事情感到满意,我想有一种方法可以从恢复模式挂载磁盘,然后进行更改。
      • 包装器应该看起来更像这样:"$(/usr/libexec/java_home)/bin/jlink" "${@}",因为它适用于当前激活的 JVM。
      • 已经有一段时间了,我将不得不重新验证,但是 IIRC,我编写了脚本来模仿 /usr/bin 中其他 Java 二进制包装脚本的行为。
      • 使用${JAVA_HOME} 有其优势,因为它允许您通过导出此变量的新值来动态更改JDK。这也是一个缺点,因为您实际上必须导出它。 (JAVA_HOME 默认不设置)。
      • 这绝对是一个权衡。在我看来,由于我只是在填补另一个解决方案的空白,因此将我的决定与他们的决定保持一致比独立做出决定更为谨慎。如果它们不对齐,那么/usr/bin/jlink 可能指向与/usr/bin/javac 不同的JDK。那会很糟糕!
      猜你喜欢
      • 2018-10-29
      • 2018-03-06
      • 1970-01-01
      • 2011-05-27
      • 2018-10-07
      • 2019-03-07
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      相关资源
      最近更新 更多