为Mac打包Java 7 .jar文件

10
我创建了一个需要Java 7的.jar文件。我已经安装了Java 7(JDK和JRE),可以双击运行.jar文件。但是,我想将其打包成一个应用程序。
我尝试过使用苹果的Jar Bundler工具成功地创建了一个应用程序;然而,当我运行它时,它很快就会在Dock中出现并消失。当我从终端运行内部文件JavaApplicationStub时,我得到以下信息:
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/lcmmun/kiosk/gui/Kiosk : Unsupported major.minor version 51.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at apple.launcher.LaunchRunner.loadMainMethod(LaunchRunner.java:56)
    at apple.launcher.LaunchRunner.run(LaunchRunner.java:112)
    at apple.launcher.LaunchRunner.callMain(LaunchRunner.java:51)
    at apple.launcher.JavaApplicationLauncher.launch(JavaApplicationLauncher.java:52)

根据 "unsupportedclassversionerror unsupported major.minor version 51.0 unable to load class" 的提示,意味着我没有安装Java 7。但是我已经安装了。

因此,我的假设是 JavaApplicationStub 不兼容Java 7。

我也听说过an ANT task可以完成同样的任务,但它似乎太复杂了,而且我不知道如何使用ANT。如果这真的是解决方案,我很乐意学习。

编辑:我现在也尝试了Eclipse的导出 > 其他 > Mac OS应用程序包。这也失败了。

我正在运行10.8 Mountain Lion,64位。

"我创建了一个需要Java 7的.jar文件" 它使用了哪些Java 7功能? "我想将其打包成一个应用程序。" 为什么不使用Java Web Start部署它呢? - Andrew Thompson
@AndrewThompson:Java Web Start - 有趣。我需要重写很多代码吗?我有文件加载/保存和Desktop.open,还有大量的Swing代码。 - wchargin
要使用常规的文件I/O或使用“桌面”API,代码需要由您进行数字签名并得到最终用户的信任(在提示时单击“确定”)。这不需要对代码进行任何更改。只有通过JWS启动的应用程序才能使用某些API,这些API提供了一种略微不同且更有限的文件I/O桌面形式,但是要使用这些API需要对代码进行更改。 - Andrew Thompson
好的。我假设支持首选项 API (java.util.prefs)? - wchargin
所有的J2SE类都支持使用JWS启动的受信任应用程序。 - Andrew Thompson
如果你希望任何人在不需要先安装其他东西的情况下使用你的应用程序,那么Java 7可能不是一个好选择。 - jahroy
1个回答

17

问题

您的假设是正确的,苹果公司的JavaApplicationStub位于此位置:

  • System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub

该程序只兼容苹果自己为Mac OS X构建的Java包。

原因

苹果正在停止使用自己的Java系统包,并在逐步退出过程中仅支持Java 6。Oracle现在接管并提供Mac OS X的Java 7,从10.7.3开始。苹果甚至没有任何通知就停止了开发工具,例如Jar Bundler.app,您可以在此帖子中看到:

一些人甚至绝望地尝试手动增加Info.plist中由苹果的JavaApplicationStub读取的JVMVersion属性值,从文档化的字面值1.61.6+到未经记录的字面值,如1.7。这也行不通,即使您已安装Oracles Java 7包,您最终也会遇到这样的对话框。

UserNotificationCenter

因此,在已经淘汰的苹果Java 6世界和未来的Oracle Java 7世界之间,您很可能会发现其他不一致之处。

解决方案

要基于Oracles Java 7构建应用程序包,您需要使用Oracles AppBundler Ant任务,其中包含OraclesJavaAppLauncher。现在这个任务只支持Mac OS X的Oracles Java 7,并且与苹果自己的Java系统包不兼容。

好消息是,您现在可以将Oracles Java 7 JRE内联到您的应用程序包中。它将包含在目录

  • Contents/PlugIns

例如在应用程序包中。

  • Contents/PlugIns/jdk1.7.0_17.jdk
这意味着您的应用程序包是完全自包含的,可以直接部署到App Store。
但您也可以依赖于已安装的Oracle Java 7软件包。
如需更详细的答案,您还应该查看以下内容:

那么没有办法让应用程序只运行java -jar我的jar文件吗?我有没有办法将一个简单的bash脚本嵌入到我的应用程序中作为可执行文件?像这样的东西可以很好地完成工作;然后我就不必担心JDK提供者等问题了。 - wchargin
1
当然有,但这里的问题是如何以苹果的方式启动Java应用程序,也称为OSX App-Bundles。因此,您可以使用集成在OSX应用程序包中的存根来启动Java主类,而不是使用“java”二进制文件。 - Uwe Günther
1
那么,“什么是将Java 7 jar文件打包成本地Mac应用程序的最简单、最便携的方法?”这个问题应该单独提出来吗? - wchargin
2
大家好,谢谢你们的问题和回答。由于这个回答是2013年的,你们有没有遇到更好的方法来为Mac打包Java应用程序呢? - Jack
@MarkLalor,它有问题,我尝试按照这个解决方案打包我的应用程序,但没有成功。我不太记得问题是什么,但从我的评论中可以看出,其中一些提到的应用程序不兼容或已经不存在了。这就是为什么我问是否有任何更新的原因。 - Jack
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接