9

有谁知道如何将 Java 运行时嵌入到 Mac Cocoa(沙盒)应用程序中,以便该应用程序可以运行 .jar 文件,而无需用户单独安装 Java?

我们有一个 Cocoa 应用程序,我们通过 Mac App Store 以及我们自己的网站销售,它可以使用 Java 完成特定任务。这是一个写作应用程序,并且因为 .doc、.docx 和 .odt 的标准 NSText 导出器非常有限(不支持页眉、页脚、图像等),我们将其写入 RTF,然后使用基于 Java 的转换器(来自 Aspose. com) 将 RTF 转换为 .doc、.docx 或 .odt,具体取决于所选的导出格式。

为此,我使用 NSTask 调用 /usr/bin/java 并运行一个捆绑的 .jar 文件来运行转换例程。这一切都很好——只要在用户的 Mac 上安装了 Java。如果未安装,我们的应用程序会询问用户是否愿意安装 Java 以从增强的转换器中受益,或者转而使用 NSText 有损转换器。如果用户选择安装 Java,我们调用 java_home --request 来调用 OS X 的 Java 安装程序。

然而,既然 Apple 已经结束(或正在结束)对 Java 的直接支持,这种方法是有问题的。在我们上次 Mac App Store 审查期间,我们被告知我们很快就需要停止询问用户是否要安装 Java。我读过 Apple 推荐的前进路线是将 Java 运行时环境嵌入到需要运行 Java 的 Cocoa 应用程序中。(例如: http: //lists.apple.com/archives/java-dev/2011/Jul/msg00038.html

因此,在过去的几天里,我一直在研究如何在我的应用程序中嵌入 JRE,但我没有找到任何关于如何在任何地方这样做的说明——至少我没有理解。几年前有人在这里问过类似的问题:

在 Mac OS X 上捆绑私有 JRE

但是,那里以及我在其他网站上找到的答案都是关于将 Java 应用程序捆绑为 Mac 应用程序,而不是在现有 Cocoa 应用程序中包含 JRE。(虽然我承认我缺乏 Java 经验可能意味着我只是不明白如何为我的目的转换指令 - 让我离开 Xcode,我就离开了我的舒适区。)同样:https:/ /wikis.oracle.com/display/OpenJDK/How+to+embed+a+.jre+bundle+in+your+Mac+app

似乎有几个应用程序已经做到了这一点(例如 Cyber​​duck),但还没有人记录这个过程。根据我的阅读,我认为我需要从 Oracle 的 JDK 或 OpenJDK 中获取 Java 虚拟机并将其包含在我的 Cocoa 应用程序中并从其中调用 java,但如果我这样做了,副本中的 Java 可执行文件JVM 不会被沙盒化,所以我的应用程序不会通过 MAS 审查过程。所以大概我需要以某种方式构建 JDK 的副本并将其沙箱化,很可能作为我更大的 Xcode 项目的一部分?我什至不知道从哪里开始;我猜现在还处于早期阶段,而且还没有多少 Mac 开发人员不得不这样做。

有没有人有任何将 JRE 嵌入到 Cocoa 应用程序中的经验,该应用程序可以使用 NSTask 调用它?并且 JRE 是完全沙盒化的,因此可以被 Mac App Store 接受?或者,有没有人成功地创建了一个沙盒化的 Cocoa 应用程序,它运行一个 .jar 文件而不需要单独的 Java 安装?如果是这样,你愿意分享你是如何做到的吗?

(我向 Apple 提出了一个开发人员技术支持事件寻求帮助,但被告知他们根本无法提供帮助,因为 Java 现在被认为是第三方开发环境。)

非常感谢您对我可能错过的网页的任何建议或指示。

4

2 回答 2

1

我不能确定,但​​我强烈怀疑当那个 Apple 工程师说他们建议“嵌入”Java 运行时时,他并不是说“将单独的可执行文件捆绑到您的应用程序包中并在单独的进程中运行”因为他的意思是“在您自己的进程中启动 Java VM 并在该 VM 中运行您需要的东西”。可以说,这样做比在单独的进程中运行 Java 更麻烦,但这是可能的。

看看NSJavaVirtualMachine课堂。如果用户没有安装 Java,它可能对您没有帮助,但想法是一样的 - 您只需构建一个包含 Java 运行时的库,将其链接到您的主二进制文件,然后使用创建和管理 JVM JNI API。谷歌为JNI_CreateJavaVM.

我在另一个问题( Calling a Java class function from Cocoa with JNI )中给出了一个简单的例子,即假脱机一个 JVM 并使用 JNI调用 Java ,尽管这是基于使用 Apple 捆绑的 JavaVM.framework,所以它没有包括构建您需要链接的库的步骤。不幸的是,我没有任何经验。

于 2013-06-06T12:26:23.703 回答
1

要回答您关于沙盒和辅助二进制文件的子问题,这不是问题。您只需将二进制文件标记为继承沙箱。

有一个.entitlements这样的文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.inherit</key>
    <true/>
</dict>
</plist>

并确保您在 Xcode 中有一个构建阶段,用于对 aux 二进制文件进行代码设计:

codesign --entitlements myjava.entitlements -s "${CODE_SIGN_IDENTITY}" java
于 2013-09-13T13:58:12.473 回答