35

我正在使用安装了 Oracle 的 Java 7 的 Mac OS X 测试我当前的应用程序。它使用的是 Apple 的 Java 6,而不是使用 Oracle 的 Java 7。的默认系统输出java -version是显示7

我尝试了不同站点中提到的大部分内容,但无法解决此问题。

JAVA_HOME也设置得当。

我仅将 Mac 用于测试目的。我真的需要一些指导。

当我通过选择 JRE 7 使用 Eclipse 运行它时,它运行正常。因此,应用程序没有任何问题。我在 Mac OS X 上遗漏了一些东西。

我的 Java 系统环境如下所示:

  • OS X 版本

    10.8

  • /usr/libexec/java_home -V

    Matching Java Virtual Machines (3):
    1.7.0_12, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk   
    1.6.0_37-b06-434, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_37-b06-434, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    
    /Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk/Contents/Home
    
  • /usr/libexec/java_home

    /Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk/Contents/Home
    
  • echo $JAVA_HOME

    /Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk/Contents/Home/
    
  • JAVA_ARCH未设置

  • /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version

    java version "1.7.0_12-ea"
    
  • ls /Library/Java/JavaVirtualMachines

    jdk1.7.0_12.jdk
    
  • /System/Library/Frameworks/JavaVM.framework/Commands/java -version

    java version "1.6.0_37"
    

我想我当前的 JDK 指向错误。

4

5 回答 5

90

问题

您的 Mac OS X 应用程序包是使用与 Oracle 的 Java 7 包不兼容的应用程序捆绑器创建的。例如,您使用的捆绑器可能Jar Bundler由 Apple 提供,它仅适用于 Apple 的 Java 6 系统包。

从 Java 7 及更高版本开始,Apple 已放弃对 Java 作为集成系统包的支持。因此,您必须选择 Oracle Java 7 第三方包及其应用程序包捆绑解决方案。这允许您在 Mac OS X 10.7.3 及更高版本上创建和部署基于 Oracle Java 7 的应用程序包。

您面临的潜在技术问题是 Apple 基于本机Objective-CJavaAppLauncher二进制文件,它使用的格式Info.plist仅适用于 Apple 的 Java 6 System Packages,而JavaAppLauncher Info.plist来自 Oracle 的组合仅适用于 Oracle 的 Java 7 Packages。

当您使用JavaAppLauncher支持 Apple 的 Java 6 系统包时,它将始终选择安装在您的 Mac 上的 Apple Java 6 系统包。

有一个视频,Oracle 的 Java 平台 Mac OS X 端口的首席工程师 Scott Kovatch 在 DEVOXX 上详细讨论了 Oracle Java 7 的应用程序捆绑是如何工作的。

解决方案

创建基于 Mac OS X 10.7.3 及更高版本的应用程序包

及以上,您必须使用 Oracle 的 app bundler

使用 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并移动到<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为您的应用程序数据。您可以在此处找到一些其他AppBundlerTask选项,因为此示例仅以最简单的形式显示它是如何工作的。

  • 运行bundle目标后,ant bundle您将MyJavaMacOSXApp.app<project>/dist目录中找到。

<runtime dir="${env.JAVA_HOME}" />元素是什么?

内联 Oracle Java 7 包 (JRE)

上面的 Ant 目标从您的

  • JAVA_HOME

进入

  • MyJavaMacOSXApp.app/Contents/PlugIns

因此,应用程序包是完全独立的,根本不需要在目标系统上安装 Oracle Java 7 包 (JRE)。就像您在以下已部署的屏幕截图中看到的那样MyJavaMacOSXApp.app

MyJavaMacOSXApp 内联 JRE

连接默认 Oracle Java 7 包 (JRE)

如果要使用安装在应用程序包目标 Mac 下的默认 Oracle Java 7 包 (JRE)

  • /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/

你必须删除

  • <runtime dir="${env.JAVA_HOME}" />

任务中的元素bundle。就像您在以下已部署的屏幕截图中看到的那样MyJavaMacOSXApp.app

MyJavaMacOSXApp 内联 JRE

来源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中读取*.jars 。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> 

此答案基于的重要文件:

  1. http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/packagingAppsForMac.html
  2. http://java.net/projects/appbundler/pages/Home
  3. http://java.net/downloads/appbundler/appbundler.html
  4. http://intransitione.com/blog/take-java-to-app-store/
  5. http://www.parleys.com/#st=5&id=2891&sl=37

appbundle 本身也有一个维护良好的分支,具有更多功能和错误修复。

于 2013-03-07T12:37:43.327 回答
4

应用程序所需的 Java 版本可能在应用程序的元数据中指定。如果您右键单击应用程序并选择显示包内容并浏览到Info.plist文件,您应该会找到定义应用程序将使用的 JVM 的条目。例如

    <key>JVMVersion</key>
    <string>1.5</string>

如果应用程序请求它,OSX 可能会选择使用较低的 JVM。

于 2013-02-11T06:14:32.620 回答
4

你的系统不是最新的。我并不是说这会导致您的问题。但为了安全起见,我将扮演最新和最伟大的角色。

  1. 通过系统更新角色您的系统,您在 Mac OS X 10.8.2 上
  2. 从 Apple aka Java for OS X 2013-002安装新的 JRE 1.6.0_43
  3. 从 Apple aka Java for OS X 2013-002 Developer Package Mar 4, 2013安装新的 JDK 1.6.0_43 。为了获得 Apple JDK,您必须在此处使用您的 Apple ID(免费开发者帐户)登录并搜索术语“Java for OS X 2013-002 Developer Package”。不幸的是,该软件包没有直接链接。
  4. 删除您过时的 Oracle JDK sudo rm -rf /Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk:. 注意:这是安全的,因为下一步我们将安装当前的 Oracle JDK 1.7.0_17。
  5. 下载并安装适用于 Mac OS X 的 Oracle JDK 1.7.0_17。注意:这也包括来自 Oracle 的 JRE 1.7.0_17。
  6. 重新启动。

完成上述所有步骤后,请再次提出以下输出:

  1. 您使用哪个 OS X 版本?
  2. 什么转储了命令/usr/libexec/java_home -V
  3. 什么转储了命令/usr/libexec/java_home
  4. 什么转储了命令echo $JAVA_HOME
  5. 什么转储了命令echo $JAVA_ARCH
  6. 什么转储了命令/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version
  7. 什么转储了命令ls /Library/Java/JavaVirtualMachines
  8. 什么转储了命令/System/Library/Frameworks/JavaVM.framework/Commands/java -version

只需记录您在原始问题中所做的步骤和努力。所以它反映了你的进步。

更新:解决方案是使用 Oracles 创建一个 Mac OS X 应用程序包AppBundlerTask。有关详细信息,请参阅我的其他答案: https ://stackoverflow.com/a/15271448

于 2013-03-07T10:53:36.527 回答
1

编辑:Uwe 令人印象深刻的答案对于使用 AppLauncher 的 OP 来说是绝对正确的。我对这个问题的初步阅读是它与使用 Java 6 和 Java 7 的 OSX 上的命令行问题有关。对原始问题的评论表明我错了。但是,任何有命令行问题的人都可能会发现以下更简单的解决方案。

原文:我的情况似乎与我认为的 OP 相同:Java 1.7 在命令行上完美,但mvn失败并抱怨 1.6,使用sbtIntelliJ 的一般编译工作正常。我只是开始在使用mvn.

我发现这很好用并且更简单:

http://www.jayway.com/2013/03/08/configuring-maven-to-use-java-7-on-mac-os-x/

我需要的只是.profile中的以下内容:

export JAVA_HOME=`/usr/libexec/java_home -v 1.7`

设置该变量并mvn运行良好。

于 2013-07-31T05:00:56.787 回答
1

尝试安装这个:

http://support.apple.com/kb/dl1572

InteliJ 工作得很好,而我仍在使用例如 NetBeans 的 Java SE 7。

java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
于 2014-11-04T12:49:37.617 回答