我有一个在 Mac OS X 上运行的 Java 应用程序(捆绑在 .app 文件中),其中包含 2 个 Jar 文件。一个 Jar 运行另一个 Jar 以传递一些变体参数。 我还在应用程序中嵌入了 JRE,因此用户根本不必担心下载 Java。问题是当用户运行应用程序时, 第一个 Jar 使用嵌入式 JRE 运行良好,但是当它尝试通过此示例代码运行第二个 Jar 时:
String jarPath = "MyMainJar.jar"
String [] cmd = { "java", "-jar", "-noverify", jarPath };
ProcessBuilder processBuilder = new ProcessBuilder( cmd );
Process process = processBuilder.start();
在终端中打印: 不存在 Java 运行时,请求安装。
如果我安装 JDK,一切都会正常工作,但这里的主要思想是我嵌入了 JRE,这样用户就不会担心这些 Java 问题并安装它。 所以我的问题是:
- 我的嵌入式 JRE 在“bin”文件夹中具有“java”工具。为什么第一个Jar不能使用呢?为什么一定要JDK?
- 我可以在我的应用中嵌入 JDK 而不是 JRE 吗?
- 我可以在向用户显示 Mac OS 消息之前检测代码中的此问题,以便向他显示更好的消息吗?
- 还有其他建议的解决方案可以解决此问题而不要求用户在 Mac 上安装 JDK 吗?
最佳答案
当您在没有绝对路径的情况下指定 java
时,通过系统特定命令搜索路径解析它可能最终会得到不同 java 安装的可执行文件。
要强制使用已运行的同一 JVM,请根据 java.home
系统属性解析该命令。
String jarPath = "MyMainJar.jar";
String jarCmd = Paths.get(System.getProperty("java.home"), "bin", "java").toString();
String [] cmd = { jarCmd, "-jar", jarPath };
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
Process process = processBuilder.start();
顺便说一句,不要使用-noverify
。这种选择的好处(如果有的话)并不能证明其风险是合理的。
此外,如果您不打算将构造的输入提供给新进程或解析其输出,则值得将 .inheritIO()
链接到 ProcessBuilder
,因此新进程将使用与父进程相同的输入/输出 channel ,而不是创建管道。
关于Java - Mac 应用程序需要安装 JDK 才能运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56397953/