为什么它会锁定lib / modules?

时间:2018-01-06 20:28:45

标签: java windows java-9

当我启动任何第三方应用程序时,例如记事本(但你可以采取其他任何东西),从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文件。这使得我们的Java应用程序很难通过私有JRE进行自我更新,因为原始目录(包含JRE)无法重命名。这是ProcessExplorer(Sysinternals)的截图:

Screenshot of ProcessExplorer showing the notepad process launched by Java 9

这有点像Java 9错误(报告为JDK-8194734),但是可以解决在Windows上启动应用程序而不锁定lib\modules文件的问题,例如通过使用外部(代理)应用程序,只需将传递的参数作为应用程序启动?

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

如果您有Oracle Java支持合同,则应通过支持渠道询问何时即将修复。

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

如果您真的非常渴望修复,请考虑执行以下操作:

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

  2. 找出错误的位置。你似乎知道它是什么,所以不难想出去哪里看。

  3. 开发修复bug。

  4. 将修补程序作为修补程序提供给OpenJDK项目。

  5. 这将增加在标准代码库及其产生的分布中更快地修复问题的可能性。它还将为您提供内部测试的解决方案,以及愿意使用您的"固定" JVM。

    我提到了一种可能的解决方法,包括重新处理您拒绝的代码。还有其他人。 AFAIK没有任何解决方法可以帮助您,无论如何。