【问题标题】:Why does it keep lib/modules locked?为什么它保持 lib/modules 锁定?
【发布时间】:2018-01-06 20:28:44
【问题描述】:

当我启动任何第三方应用程序时,例如记事本(但您可以使用其他任何内容),从 Java 9 应用程序中退出,然后退出 Java 应用程序:

import java.io.*;

public class LaunchNotepad {
  public static void main(String[] args) throws IOException {
    Runtime.getRuntime().exec(new String[] {"C:\\Windows\\notepad.exe"});
  }
}

启动的第三方应用程序一直锁定 Java 9 的 lib\modules 文件。这使得我们的具有私有 JRE 的 Java 应用程序很难自行更新,因为无法重命名原始目录(包含 JRE)。这是来自 ProcessExplorer (Sysinternals) 的屏幕截图:

这闻起来像 Java 9 错误(报告为 JDK-8194734),但是否有解决方法可以在不锁定 lib\modules 文件的情况下在 Windows 上启动应用程序,例如通过使用将传递的参数作为应用程序简单地启动的外部(代理)应用程序?

【问题讨论】:

  • lib/modules 文件的句柄不应该被继承到子进程中。如果您确定发生这种情况,请提交错误。
  • 我已经提交了一个错误,但我不知道 Oracle 需要多长时间来修复它。我需要一个快速的解决方法,即使它很脏。我有点沮丧,人们搁置这个问题,因为这并不能解决任何问题。
  • 你试过Runtime.getRuntime().exec(new String[] {"cmd", "/c", "start", "C:\\Windows\\notepad.exe"});吗?这样,锁定 lib/modules 的 cmd 进程将立即退出,只留下记事本运行。
  • 什么是c:\temp\java-test文件?
  • 问题已更新,屏幕截图显示 Notepad.exe 继承了 jimage 文件的句柄。现在在 JDK JIRA 中对此进行了跟踪:bugs.openjdk.java.net/browse/JDK-8194734

标签: java windows java-9


【解决方案1】:

fixed this bug。这算作一种解决方法吗? :)

否则,确实有一些解决方法。

解决方法 1:使用 awt.Desktop

扫描Java源码,发现awt.Desktop可以为我们调用ShellExecute

不幸的是,此方法不允许传递命令行参数。您可以将临时批处理文件写入磁盘并启动它作为解决方法。

import java.io.*;
import java.awt.Desktop;

public class LaunchNotepad {
  public static void main(String[] args) throws IOException {
    File program = new File("C:\\Windows\\notepad.exe");
    Desktop.getDesktop().open(program);
  }
}

解决方法 2:使用 PsExec 作为代理

SysInternals PsExec 不会将文件继承到以它启动的进程中。请记住使用-d 参数,否则 PsExec 本身将保存该文件。

使用cmd.exe 作为代理是不可能的,因为它总是继承句柄。

解决方法 3:制作自己的代理

您需要使用两个 WINAPI 之一:CreateProcess(指定 bInheritHandles=FALSE)或 ShellExecute

【讨论】:

    【解决方案2】:

    如果您有 Oracle Java 支持合同,您应该通过支持渠道询问何时会提供修复。

    更新 - 基于https://bugs.openjdk.java.net/browse/JDK-8194734,当前答案可能是“Java 11 发布时”。但 Oracle 可能会决定将修复程序向后移植到 Java 9 和 10。

    如果您真的迫切需要修复,请考虑执行以下操作:

    1. 下载 OpenJDK 源代码并构建自己的 JVM。

    2. 找出错误所在。你似乎知道它是什么,所以应该不难找出去哪里看。

    3. 为该错误开发修复程序。

    4. 将修复作为补丁贡献给 OpenJDK 项目。

    这将增加问题在标准代码库和由此产生的发行版中更快得到修复的可能性。它还将为您提供内部测试和愿意使用您的“固定”JVM 的客户的解决方法。

    我提到了一种可能的解决方法,它涉及重新编写您立即拒绝的代码。还有其他人。 AFAIK 没有不涉及为您工作的解决方法,无论哪种方式。

    【讨论】:

    • 请解释否决票。您不喜欢该答案这一事实并不会使其成为无用的答案。事实上,当没有简单的答案时,显然告诉某人没有简单的答案,这样他们就不会浪费时间等待答案。请注意,您现在已经等待了 2 周,
    • 您的答案可能是 JDK 开发人员的解决方法,但不适用于没有 Windows API 知识的普通 Java 开发人员。目前,我们的解决方法是继续使用 Java 8。
    • 我建议的另一个想法适用于普通的 Java 开发人员,假设他们能够开发批处理文件......或本机代码启动器。如果坚持使用 Java 8 是一种解决方法,那么在你问这个问题之前你就有了:-)
    • 如果坚持使用 Java 8 是一种可行的解决方法,那么在你问这个问题之前你就已经知道了。那么甲骨文没有足够快地为您修复错误是怎么回事?请耐心等待。
    • 另一个答案完全证实了您的说法,即它应该是一个简单的解决方法:)
    猜你喜欢
    • 2022-10-13
    • 2012-12-09
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2017-02-23
    • 2015-12-22
    相关资源
    最近更新 更多