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

问题描述:

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

Does anybody know how to embed a Java runtime into a Mac Cocoa (sandboxed) app so that the app can run a .jar file without the user having to install Java separately?

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

We have a Cocoa application that we sell through the Mac App Store as well as on our own site which can use Java for a specific task. It's a writing app, and because the standard NSText exporters for .doc, .docx and .odt are very limited (not supporting headers, footers, images etc), we write out to RTF and then use Java-based converters (from Aspose.com) to convert the RTF to .doc, .docx or .odt, depending on the chosen export format.

我通过使用NSTask调用/usr/bin/java并运行一个捆绑的.jar文件来执行此操作,该文件运行转换例程.只要在用户的Mac上安装了Java,这一切都可以很好地工作.如果尚未安装,我们的应用程序会询问用户他或她是否想安装Java以从增强型转换器中受益,还是退回到NSText有损转换器上.如果用户选择安装Java,则我们调用java_home --request来调用OS X的Java安装程序.

I do this by by using NSTask to call on /usr/bin/java and run a bundled .jar file that runs the conversion routines. This all works beautifully--as long as Java is installed on the user's Mac. If it's not installed, our app asks the user if he or she would like to install Java to benefit from the enhanced converters, or instead fall back on the NSText lossy converters. If the user chooses to install Java, we call java_home --request to invoke OS X's Java installer.

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

However, now that Apple has ended (or is ending) direct support for Java, this approach is problematic. During our last Mac App Store review, we were told that we would soon need to stop asking the user if he or she wanted to install Java. I have read that Apple's recommended route going forward is to embed a Java Runtime Environment into Cocoa applications that need to run Java. (E.g: http://lists.apple.com/archives/java-dev/2011/Jul/msg00038.html )

因此,在过去的几天中,我一直在研究如何在应用程序中嵌入JRE,但是我没有找到有关如何在任何地方进行JRE的说明-至少我不了解.几年前有人在这里问过类似的问题:

Over the past few days, I've therefore been researching how I can go about embedding a JRE in my app, but I haven't found any instructions on how to do so anywhere - nothing that I understand, at least. Someone asked a similar question here a couple of years ago:

在Mac OS X上捆绑私有JRE

但是,在那里以及在其他网站上找到的答案都是关于将Java应用程序捆绑为Mac应用程序,而不是将JRE与现有的Cocoa应用程序结合在一起. (尽管我接受我缺乏Java经验,这可能意味着我只是不了解如何为我的目的转换指令-将我带出Xcode,使我脱离了自己的舒适范围.)同样: https://wikis.oracle .com/display/OpenJDK/How + to + embed + a + .jre + bundle + in + your + Mac + app

However, the answers there, and on other sites I've found, are all about bundling a Java application as a Mac application, not about including a JRE with an existing Cocoa application. (Although I accept that my lack of experience with Java may mean that I just don't understand how to convert the instructions for my purposes - take me out of Xcode and I'm out of my comfort zone.) Likewise: https://wikis.oracle.com/display/OpenJDK/How+to+embed+a+.jre+bundle+in+your+Mac+app

似乎有几个应用程序已完成此操作(例如Cyber​​duck),但尚未有人记录该过程.从我所读的内容中,我认为我需要从Oracle的JDK或OpenJDK中获取Java虚拟机,并将其包含在我的Cocoa应用程序中,然后在其中调用Java,但是如果这样做的话,不会将JVM副本中的Java可执行文件沙盒化,因此我的应用程序将无法通过MAS审核过程.因此,大概我需要以某种方式构建JDK的副本并将其沙箱化,这很可能是我的大型Xcode项目的一部分?我什至不知道从哪里开始.我猜这还处于初期,还没有很多Mac开发人员必须这样做.

It seems that a couple of applications have done this (e.g. Cyberduck), but no one has documented the process yet. From what I've read, I think I need to either grab the Java Virtual Machine from Oracle's JDK or OpenJDK and include that in my Cocoa app and call on java from within that, but if I did so, the Java executables within the copy of the JVM wouldn't be sandboxed, so my app wouldn't get through the MAS review process. So presumably I need to somehow build a copy of the JDK and sandbox it, most likely as part of my larger Xcode project? I'm not even sure where to start; I'm guessing it's still early days and that not many Mac developers have had to do this yet.

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

Has anyone got any experience of embedding a JRE into a Cocoa application in such a way that the app can just call on it using NSTask? And in such a way that the JRE is fully sandboxed and thus acceptable by the Mac App Store? Or, has anyone successfully created a sandboxed Cocoa app that runs a .jar file without needing a separate Java installation? If so, would you be willing to share how you did it?

(我与Apple发生了一次开发人员技术支持事件,寻求帮助,但被告知他们完全无济于事,因为Java现在被认为是第三方开发环境.)

(I took out a developer tech support incident with Apple asking for help on this, but was told that they couldn't help at all given that Java is now considered a third-party development environment.)

在此先感谢您对我可能错过的任何建议或指向网页的提示.

Many thanks in advance for any suggestions or pointers to web pages I may have missed.

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

To answer your sub-question about sandbox and aux binaries, that's not a problem. You just have to mark the binary as inheriting the sandbox.

具有这样的.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二进制文件进行了代码签名:

And make sure you have a build phase in Xcode that codesigns the aux binary:

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