如何将Java应用程序捆绑到Mac OS X * .app捆绑包? [英] How to bundle a Java application to a Mac OS X *.app bundle?

查看:135
本文介绍了如何将Java应用程序捆绑到Mac OS X * .app捆绑包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Java应用程序捆绑到Mac OS X .app捆绑包中.我目前正在使用 appbundler ,并且我关注了 Oracle指南.Ant任务在Netbeans中工作正常,并且相应的.app程序包已正确构建(在Windows上).但是,当尝试对我的MacBookPro(OS X 10.7.5)执行.app程序包时,在日志中出现以下错误:

I am trying to bundle my Java application to an Mac OS X .app bundle. I am currently using appbundler and I followed Oracle's guide. The Ant task works fine in Netbeans and the corresponding .app package is built correctly (on Windows). But when trying to execute the .app package to my MacBookPro (OS X 10.7.5), I get the following error in the log:

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

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

I already checked the permissions for the .jar file and the execution bits are set for the main-jar and all the jars in the lib-folder.

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

The application just runs fine when typing the following to the terminal:

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

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

For clarification, here's the final folder structure:

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中复制这些库?还是可以随后手动复制它们?

By the way, my application has lots of external dependencies, all located in the "lib" folder which are properly linked by the class-path property within the MANIFEST.MF file of the executable main-jar file "LawSuiteSE.jar". Do I need to copy these libs within the appbundle-ant-task or is it okay to copy them subsequently by hand?

我还尝试在MacBook Pro上构建应用程序和相应的.app程序包,但是出现了相同的错误消息.

I also tried to build the application and the corresponding .app package on the MacBook Pro, but the same error message.

这是我的蚂蚁任务:

<!-- 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:

I meanwhile replaced the JavaAppLauncher in Contents/MacOS with a small run script (start.sh):

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

然后,我还将 Info.plist 中的键 CFBundleExecutable 的值从 JavaAppLauncher 替换为 start.sh .

Then I also replaced the value for the key CFBundleExecutable in Info.plist from JavaAppLauncher to start.sh.

现在它可以正常工作,但是如何使用jar可执行文件的相对路径?诸如"../Java/LawSuiteSE.jar"之类的东西无法正常工作,并给我与以前相同的错误.是否有指向当前应用程序文件夹的常量,例如"$ APP_ROOT",以便脚本看起来像这样:

Now it works fine, but how can I use a relative path to the jar-executable? Something like "../Java/LawSuiteSE.jar" doesn't work and gives me the same error as before. Is there any constant pointing to the current app-folder, something like "$APP_ROOT" so that the script could look like:

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

有什么想法吗?

推荐答案

我是否需要在appbundle-ant-task中复制这些库

Do I need to copy these libs within the appbundle-ant-task

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

Yes, you should mention all the required libraries in classpath elements. The bundler will then copy them all to the appropriate place inside the bundle (only JAR files that are directly under Contents/Java will go onto the classpath when the bundle is run, JARs in subdirectories are ignored). You should also use dots instead of slashes in the 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可执行文件的相对路径

Now it works fine, but how can I use a relative path to the jar-executable

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

You can use dirname $0 to get the path to your bundle's Contents/MacOS, and take a relative path from there. You should probably also make an explicit reference to the public JRE rather than relying on java being on your PATH, as that will only work if the target machine has a JDK installed, not if it only has a JRE. Installing the JDK will install the public JRE as well, so it's safe in that case too.

#!/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

这篇关于如何将Java应用程序捆绑到Mac OS X * .app捆绑包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆