当我启动任何第三方应用程序时,例如记事本(但你可以采取其他任何东西),从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)的截图:
这有点像Java 9错误(报告为JDK-8194734),但是可以解决在Windows上启动应用程序而不锁定lib\modules
文件的问题,例如通过使用外部(代理)应用程序,只需将传递的参数作为应用程序启动?
答案 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。
如果您真的非常渴望修复,请考虑执行以下操作:
下载OpenJDK源代码并构建您自己的JVM。
找出错误的位置。你似乎知道它是什么,所以不难想出去哪里看。
开发修复bug。
将修补程序作为修补程序提供给OpenJDK项目。
这将增加在标准代码库及其产生的分布中更快地修复问题的可能性。它还将为您提供内部测试的解决方案,以及愿意使用您的"固定" JVM。
我提到了一种可能的解决方法,包括重新处理您拒绝的代码。还有其他人。 AFAIK没有任何解决方法可以帮助您,无论如何。