Issue
您的 Mac OS X 应用程序包是使用与 Oracle 的 Java 7 包不兼容的应用程序捆绑器创建的。例如,您使用的捆绑器可能是:Jar Bundler
由 Apple 提供,仅适用于 Apple 的 Java 6 系统包。
Apple 从 Java 7 及更高版本起放弃了对 Java 作为集成系统包的支持。因此,您必须选择 Oracle Java 7 第三方包及其应用程序包捆绑解决方案。这允许您在 Mac OS X 10.7.3 及更高版本上创建和部署基于 Oracle Java 7 的应用程序包。
您面临的根本技术问题是 Apple 本身的Objective-C
based JavaAppLauncher
二进制及其使用的格式Info.plist
仅适用于 Apple 的 Java 6 系统包和JavaAppLauncher
Info.plist
来自 Oracle 的组合仅适用于 Oracle 的 Java 7 包。
当您使用JavaAppLauncher
支持 Apple 的 Java 6 系统包,因此它将始终选择 Mac 上安装的 Apple Java 6 系统包。
有一个,Oracle Java 平台 Mac OS X 移植首席工程师 Scott Kovatch 在 DEVOXX 上详细介绍了 Oracle Java 7 的应用程序捆绑是如何工作的。
Solution
创建基于 Mac OS X 10.7.3 及更高版本的应用程序包
- Oracle 的 Java SE 7 (JRE 1.7.x) http://docs.oracle.com/javase/7/docs/webnotes/install/mac/mac-jdk.html
- OpenJDK Java SE 7 (JRE 1.7.x) http://openjdk.java.net/projects/macosx-port/
及以上,您必须使用 Oracle 的应用程序捆绑器
-
lib/appbundler-1.0.jar http://java.net/projects/appbundler/downloads/download/appbundler-1.0.jar包含 Ant 任务com.oracle.appbundler.AppBundlerTask http://java.net/downloads/appbundler/appbundler.html
借助 Oracle 的应用程序捆绑程序,您现在可以选择使用 Mac 上安装的默认 Oracle Java 7 包来运行打包的应用程序:
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/
或您在打包应用程序中内联的 Oracle Java 7 JRE
MyJavaMacOSXApp.app/Contents/PlugIns/
注意:这两种方法各有利弊,但如果您想使用捆绑的应用程序访问 Apple App Store,则需要使用最后一种方法并使用自己的 JRE。
需要做什么
- 下载appbundler-1.0.jar http://java.net/projects/appbundler/downloads/download/appbundler-1.0.jar并将其移至
<project>/lib/appbundler-1.0.jar
-
将以下内容添加到您的<project>/build.xml
<property environment="env" />
<taskdef
name="bundleapp"
classname="com.oracle.appbundler.AppBundlerTask"
classpath="lib/appbundler-1.0.jar" />
<target name="bundle">
<bundleapp
outputdirectory="dist"
name="MyJavaMacOSXApp"
displayname="My Java Mac OS X App"
identifier="com.example.MyJavaMacOSXApp"
shortversion="1.0"
applicationCategory="public.app-category.developer-tools"
mainclassname="com.example.MyJavaMacOSXApp">
<runtime dir="${env.JAVA_HOME}" />
<classpath file="dist/MyJavaMacOSXApp.jar" />
</bundleapp>
</target>
注意:需要更换MyJavaMacOSXApp
与您的应用程序数据。你可以找到here http://java.net/downloads/appbundler/appbundler.html一些额外的AppBundlerTask
选项,因为此示例仅显示它如何以最简单的形式工作。
运行后bundle
目标与ant bundle
你会找到MyJavaMacOSXApp.app
in the <project>/dist
目录。
什么是<runtime dir="${env.JAVA_HOME}" />
元素?
内联 Oracle Java 7 包 (JRE)
上面的 Ant 目标从您的 Oracle Java 7 Package (JRE) 复制
into
MyJavaMacOSXApp.app/Contents/PlugIns
因此,该应用程序包是完全独立的,根本不需要在目标系统上安装 Oracle Java 7 Package (JRE)。就像您在下面的此类部署的屏幕截图中看到的那样MyJavaMacOSXApp.app
:
连接默认的 Oracle Java 7 包 (JRE)
如果您想使用安装在应用程序包目标 Mac 上的默认 Oracle Java 7 包 (JRE)
-
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/
你必须删除
-
<runtime dir="${env.JAVA_HOME}" />
元素来自bundle
任务。就像您在下面的此类部署的屏幕截图中看到的那样MyJavaMacOSXApp.app
:
来源MyJavaMacOSXApp.java
package com.example;
import java.awt.*;
import javax.swing.*;
public class MyJavaMacOSXApp extends JPanel {
public MyJavaMacOSXApp() {
JLabel versionLabel = new JLabel("java.version=" + System.getProperty("java.version"));
JLabel homeLabel = new JLabel("java.home=" + System.getProperty("java.home"));
setLayout(new BorderLayout());
add(versionLabel, BorderLayout.PAGE_START);
add(homeLabel, BorderLayout.PAGE_END);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("MyJavaMacOSXApp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyJavaMacOSXApp newContentPane = new MyJavaMacOSXApp();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
如果我的应用程序有多个 jar 文件怎么办?
添加尽可能多的即可<classpath file="dist/additional.jar" />
根据您的需要输入。
注意:捆绑应用程序运行时不会保留捆绑任务中元素的顺序。这java.class.path
由本机在运行时构建JavaAppLauncher
正如它在*.jar
s from MyJavaMacOSXApp.app/Contents/Java
目录。
只是为了完整起见,这就是方法Info.plist
好像:
<?xml version="1.0" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>JavaAppLauncher</string>
<key>CFBundleIconFile</key>
<string>GenericApp.icns</string>
<key>CFBundleIdentifier</key>
<string>com.example.MyJavaMacOSXApp</string>
<key>CFBundleDisplayName</key>
<string>My Java Mac OS X App</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>MyJavaMacOSXApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>JVMRuntime</key>
<string>jdk1.7.0_17.jdk</string>
<key>JVMMainClassName</key>
<string>com.example.MyJavaMacOSXApp</string>
<key>JVMOptions</key>
<array>
</array>
<key>JVMArguments</key>
<array>
</array>
</dict>
</plist>
该答案所依据的重要文件:
- http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/packagingAppsForMac.html http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/packagingAppsForMac.html
- http://java.net/projects/appbundler/pages/Home http://java.net/projects/appbundler/pages/Home
- http://java.net/downloads/appbundler/appbundler.html http://java.net/downloads/appbundler/appbundler.html
- http://intransitione.com/blog/take-java-to-app-store/ http://intransitione.com/blog/take-java-to-app-store/
appbundler 本身还有一个维护良好的分支,具有更多功能和错误修复。
- https://bitbucket.org/infinitekind/appbundler https://bitbucket.org/infinitekind/appbundler