在您的<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
。你可以在这里找到一些额外的AppBundlerTask
选项,因为此例仅展示了其最简单的工作方式。
在使用 ant bundle
运行 bundle
目标之后,你将在 <project>/dist
目录中找到 MyJavaMacOSXApp.app
。
元素<runtime dir="${env.JAVA_HOME}" />
是什么意思?
内联 Oracle Java 7 Package (JRE)
上面的 Ant 目标将 Oracle Java 7 Package (JRE) 从您的JAVA_HOME
复制到
MyJavaMacOSXApp.app/Contents/PlugIns
因此,应用程序包完全自包含,根本不需要在目标系统上安装 Oracle Java 7 Package (JRE)。正如您可以在下面截图中看到的那样,这是一个已部署的 MyJavaMacOSXApp.app
:
![MyJavaMacOSXApp Inline JRE](https://istack.dev59.com/jkLgF.webp)
连接默认的 Oracle Java 7 Package (JRE)
如果要使用应用程序包目标 Mac 上默认的 Oracle Java 7 Package (JRE),则必须从bundle
任务中删除元素<runtime dir="${env.JAVA_HOME}" />
。正如您可以在下面截图中看到的那样,这是一个已部署的 MyJavaMacOSXApp.app
:
![MyJavaMacOSXApp Inline JRE](https://istack.dev59.com/JpBem.webp)
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" />
条目。
注意:在捆绑任务中,<classpath>
元素的顺序在捆绑后的应用程序运行时不会保留。 java.class.path
是由本机JavaAppLauncher
在运行时从MyJavaMacOSXApp.app/Contents/Java
目录中读取*.jar
。
仅为完整起见,这是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://java.net/projects/appbundler/pages/Home
- http://java.net/downloads/appbundler/appbundler.html
- http://intransitione.com/blog/take-java-to-app-store/
- http://www.parleys.com/#st=5&id=2891&sl=37
另外,还有一个维护良好的appbundler分支,带有许多更多的特性和bugfixes。