将Java运行时嵌入到沙盒Cocoa Mac应用程序中

时间:2013-06-06 11:13:36

标签: java objective-c macos cocoa

有人知道如何将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文件来实现此目的。这一切都很好用 - 只要Java安装在用户的Mac上。如果没有安装,我们的应用程序会询问用户是否要安装Java以从增强型转换器中受益,或者反过来使用NSText有损转换器。如果用户选择安装Java,我们调用java_home --request来调用OS X的Java安装程序。

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

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

Bundling a private JRE on Mac OS X

然而,那里的答案,以及我发现的其他网站上的答案都是关于将Java应用程序捆绑为Mac应用程序,而不是将JRE与现有的Cocoa应用程序包含在一起。 (虽然我接受我缺乏Java经验可能意味着我只是不明白如何将指令转换为我的目的 - 把我带出Xcode并且我不在我的舒适区。)同样:{{3 }}

似乎有几个应用程序已经这样做了(例如Cyber​​duck),但还没有人记录过这个过程。根据我的阅读,我我需要从Oracle的JDK或OpenJDK中获取Java虚拟机,并将其包含在我的Cocoa应用程序中并从内部调用java,但如果我这样做的话,JVM副本中的Java可执行文件不会被沙箱化,因此我的应用程序无法通过MAS审核过程。所以我可能需要以某种方式构建JDK和沙箱的副本,最有可能是我的大型Xcode项目的一部分?我甚至不确定从哪里开始;我猜它还处于早期阶段,并没有多少Mac开发人员必须这样做。

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

(我向Apple发起了一个开发者技术支持事件,请求帮助,但有人告诉他们,由于Java现在被认为是第三方开发环境,他们根本无法帮助。)

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

2 个答案:

答案 0 :(得分:1)

我无法确定,但我强烈怀疑当那位Apple工程师说他们建议"嵌入"在Java运行时,他并不意味着将单独的可执行文件捆绑到您的应用程序包中并在一个单独的进程中运行它#34;他的意思是在你自己的流程中启动Java VM并运行你在VM中需要的东西。"这可能比在单独的进程中运行Java更麻烦,但它是可能的。

查看NSJavaVirtualMachine课程。如果用户没有安装Java,它可能没有帮助,但想法是相同的 - 你只需构建一个包含Java Runtime的库,将其链接到主二进制文件,然后创建和管理JVM使用JNI API。 Google为JNI_CreateJavaVM

我给出了一个快速示例,假设在另一个问题(Calling a Java class function from Cocoa with JNI)中使用JNI调整JVM并调用Java,尽管这是基于使用Apple捆绑的JavaVM.framework,因此它并没有这样做。包括构建您需要链接的库的步骤。不幸的是,我对此没有任何经验。

答案 1 :(得分: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中有一个构建阶段,用于编码辅助二进制文件:

codesign --entitlements myjava.entitlements -s "${CODE_SIGN_IDENTITY}" java