如何将Java应用程序捆绑到Mac OS X * .app包中?

时间:2014-08-14 14:01:31

标签: java macos ant build jarbundler

我正在尝试将我的Java应用程序捆绑到Mac OS X .app软件包中。我目前正在使用appbundler,我跟随Oracle's guide。 Ant任务在Netbeans中运行良好,并且相应的.app包正确构建(在Windows上)。但是当我尝试将.app包执行到我的MacBookPro(OS X 10.7.5)时,我在日志中收到以下错误:

[0x0-0x72072].ch.lawsuite.core.Servitus: Error: Unable to access jarfile LawSuiteSE.jar

我已经检查了.jar文件的权限,并且为主jar和lib文件夹中的所有jar设置了执行位。

在终端输入以下内容时,应用程序运行正常:

java -jar /Applications/Servitus.app/Contents/Java/LawSuiteSE.jar --installer

为了澄清,这是最终的文件夹结构:

Servitus.app
    |_Contents
        |_Java
            |_LawSuiteSE.jar
            |_lib
                |_lib1.jar
                |_lib2.jar
                    |_subfolder1
                        |_lib3.jar
                    |_subfolder2
                        |_lib4.jar
                |_etc...
            |_MacOS
                |_JavaAppLauncher
            |_PlugIns
            |_Resources
                |_en.lproj
                    |_Localizable.strings
                |_kplus.icns
        |_Info.plist
        |_PkgInfo

顺便说一下,我的应用程序有很多外部依赖项,都位于“lib”文件夹中,它们通过可执行主jar文件“LawSuiteSE.jar”的MANIFEST.MF文件中的class-path属性正确链接。 ”。我是否需要在appbundle-ant-task中复制这些库,或者可以随后手动复制它们?

我还尝试在MacBook Pro上构建应用程序和相应的.app包,但错误信息相同。

这是我的Ant任务:

<!-- Define the appbundler task -->
<taskdef name="bundleapp" classname="com.oracle.appbundler.AppBundlerTask"/>
<!-- Create the app bundle -->
<target name="bundle-macosx">
    <bundleapp outputdirectory="macosx"
        name="Servitus"
        displayname="Servitus"
        identifier="ch.lawsuite.core.Servitus"
        shortversion="1.0"
        applicationCategory="public.app-category.business"
        icon="src/ch/lawsuite/data/icons/gmbh/osx/kplus.icns"
        mainclassname="ch.lawsuite.core.Servitus">
        <classpath file="dist/LawSuiteSE.jar"/>
        <argument value="--installer"/>
    </bundleapp>
</target>

编辑:我同时用一个小的运行脚本(start.sh)替换了Contents / MacOS中的JavaAppLauncher:

#!/bin/bash
java -Xms256m -XX:PermSize=128m -jar /Users/salocinx/Workspace/LawSuiteSE.app/Contents/Java/LawSuiteSE.jar --installer

然后我还将 InfoApp地址中的密钥 CFBundleExecutable 的值从 JavaAppLauncher 替换为 start.sh

现在它工作正常,但我怎样才能使用jar-executable的相对路径?像“../Java/LawSuiteSE.jar”这样的东西不起作用,并给我与以前相同的错误。是否有任何常量指向当前的app文件夹,类似“$ APP_ROOT”,以便脚本看起来像:

#!/bin/bash
java -Xms256m -XX:PermSize=128m -jar $APP_ROOT/Contents/Java/LawSuiteSE.jar --installer

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

  

我是否需要在appbundle-ant-task

中复制这些库

是的,您应该在classpath元素中提及所有必需的库。然后,捆绑包将它们全部复制到捆绑包内的适当位置(只有Contents/Java直接的JAR文件将在捆绑包运行时进入类路径,忽略子目录中的JAR )。您还应该在mainclassname中使用点而不是斜杠。

<bundleapp outputdirectory="macosx"
    name="Servitus"
    displayname="Servitus"
    identifier="ch.lawsuite.core.Servitus"
    shortversion="1.0"
    applicationCategory="public.app-category.business"
    icon="src/ch/lawsuite/data/icons/gmbh/osx/kplus.icns"
    mainclassname="ch.lawsuite.core.Servitus">
    <classpath file="dist/LawSuiteSE.jar"/>
    <classpath dir="lib" includes="*.jar" />
    <argument value="--installer"/>
</bundleapp>

修改

  

现在它工作正常,但我怎样才能使用jar-executable

的相对路径

您可以使用dirname $0获取套件Contents/MacOS的路径,并从那里获取相对路径。您可能还应该明确引用公共JRE,而不是依赖于java在您的PATH上,因为只有在目标计算机安装了 JDK 时才能使用,而不是只有 JRE 。安装JDK也会安装公共JRE,因此在这种情况下它也是安全的。

#!/bin/bash

SCRIPT_DIR="`dirname $0`"
exec "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java" \
  -Xms256m -XX:PermSize=128m -jar "$SCRIPT_DIR/../Java/LawSuiteSE.jar" --installer