Java - Mac 应用程序需要安装 JDK 才能运行

标签 java macos java-8 jar

我有一个在 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();

Mac 上总是出现以下错误: Mac Java App requires JDK

在终端中打印: 不存在 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/

相关文章:

java - CREATE 之后激活导致工具栏在零件堆栈中丢失

java - 向 jar 文件添加签名可防止其被加载

Mac OS X 10.5.8 上 Rails 2.3.5 的 MySQL 绑定(bind)

ios - Instashare 如何在 iOS 设备上扩展 AirDrop?

java - 使用 java 流从包含 List<String> 的 List<Object> 检索 List<String>

java - 为什么此 Java 流的一个版本在静态 map 上工作而另一个版本失败?

java - Docker:Java 8 安装在 Ubuntu 上失败

java - 如何将我经常使用的方法添加到android studio?

macos - CALayer 与 NSScrollView,缩放平移和单击

Java 8 流并从调用 boolean 方法设置属性