Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么它要锁定库/模块?_Java_Windows_Java 9 - Fatal编程技术网

Java 为什么它要锁定库/模块?

Java 为什么它要锁定库/模块?,java,windows,java-9,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应用程序启动任何第三方应用程序,例如记事本(但您可以使用其他任何东西),然后退出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(系统内部)的屏幕截图:


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

如果您有Oracle Java支持合同,您应该通过支持渠道询问何时将进行修复

更新-基于此,当前的答案可能是“当Java 11发布时”。但是Oracle可能会决定将修复程序向后移植到Java9和Java10

如果你真的想要一个解决方案,那么考虑下面的事情:

  • 下载OpenJDK源代码并构建自己的JVM

  • 找出错误所在。你似乎知道它是什么,所以应该不难找到它的位置

  • 为这个bug开发一个修复程序

  • 将修复程序作为补丁提供给OpenJDK项目

  • 这将增加在标准代码库和由此产生的分布中更快地修复问题的可能性。它还为内部测试和愿意使用“固定”JVM的客户提供了一个变通方法

    我提到了一个可能的解决方法,它涉及到重新编写您的代码,您立即拒绝了它。还有其他的。无论如何,没有一种变通办法不涉及为你工作。

    I。这算是一种解决方法吗?:)

    否则,确实可以采取一些变通办法

    解决方法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作为代理

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

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

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


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

    lib/modules文件的句柄不应继承到子进程中。如果你确定这正在发生,那么请提交一个bug。我已经提交了一个bug,但我不知道Oracle需要多长时间来修复它。我需要一个快速的工作,即使它是肮脏的。我对人们搁置这个问题感到有点沮丧,因为这并不能解决任何问题。您是否尝试过
    Runtime.getRuntime().exec(新字符串[]{“cmd”,“/c”,“start”,“c:\\Windows\\notepad.exe”})?这样,锁定lib/模块的
    cmd
    进程将立即退出,只留下记事本运行。什么是
    c:\temp\java test
    文件?问题已更新,屏幕截图显示Notepad.exe继承了jimage文件的句柄。JDK JIRA现在对此进行了跟踪:请解释否决票。你不喜欢这个答案这一事实并不意味着它是一个无用的答案。事实上,当没有简单的答案时,告诉别人没有简单的答案显然是有用的,这样他们就不会浪费时间等答案了。请注意,您已经等待了2周,您的答案可能是一个JDK开发人员的解决方案,但不是一个没有Windows API知识的普通Java开发人员的解决方案。目前,我们的工作是继续使用Java8。我建议的另一个想法适合普通Java开发人员,假设他们能够开发批处理文件。。。或本机代码启动器。如果坚持使用Java8是一种变通方法,那么在你提问之前,你已经有了这种方法:-)如果坚持使用Java8是一种可行的变通方法,那么在你提问之前,你已经有了这种方法。那么,对甲骨文没有足够快地为您修复bug而进行的所有抨击是什么意思呢?耐心点。另一个答案完全证实了你的说法,即这应该是一个简单的解决办法:)