Application is using Java 6 from Apple instead of Java 7 from Oracle on Mac OS X?

后端 未结 5 1783
走了就别回头了
走了就别回头了 2020-11-30 17:26

I am testing my current application with Mac OS X which has Java 7 from Oracle installed. Instead using Java 7 from Oracle, it\'s using Java 6 from Apple. The default system

5条回答
  •  悲哀的现实
    2020-11-30 18:19

    Issue

    Your Mac OS X application bundle has been created with an app bundler which is not compatible with Oracle's Java 7 package. The bundler you were using could be, for example, Jar Bundler provide by Apple which only works for Apple's Java 6 System Packages.

    Apple has given up support for Java as an integrated System Packages from Java 7 and later. As a consequence you have to go for the Oracle Java 7 Third Party package and their application package bundle solution. This allows you to create and deploy Oracle Java 7 based application bundles on Mac OS X 10.7.3 and onwards.

    The underlying technical issue you are facing is Apple's native Objective-C based JavaAppLauncher binary and the format it uses in Info.plist is only working with Apple's Java 6 System Packages and the JavaAppLauncher Info.plist combination coming from Oracle is only working for Oracle's Java 7 Packages.

    As you are using a JavaAppLauncher supporting Apple's Java 6 System Packages, it will always pick up the Apple Java 6 System Package installed on your Mac.

    There is a video, where Scott Kovatch, the lead engineer for the Mac OS X port of the Java platform at Oracle is talking on DEVOXX about how app bundling for Oracle Java 7 is working in great detail.

    Solution

    To create app bundles based for Mac OS X 10.7.3 and onwards based on

    • Oracle's Java SE 7 (JRE 1.7.x)
    • OpenJDK Java SE 7 (JRE 1.7.x)

    and above, you have to use Oracle's app bundler

    • lib/appbundler-1.0.jar containing the Ant Task com.oracle.appbundler.AppBundlerTask

    With Oracle's app bundler you have now the choice to run your packaged app with the default Oracle Java 7 Package installed on your Mac here:

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

    or the Oracle Java 7 JRE you inline in your packaged application

    • MyJavaMacOSXApp.app/Contents/PlugIns/

    Note: There are pros and cons for both approaches, but you need the last one with your own JRE if you want to go to the Apple App Store with your bundled app.

    What needs to be done

    • Download appbundler-1.0.jar and move it to /lib/appbundler-1.0.jar
    • Add the following to your /build.xml

      
      
      
      
      
          
              
              
          
      
      

      Note: You need to replace MyJavaMacOSXApp with your application data. You can find here some additional AppBundlerTask options, as this example shows only how how it works in its simplest form.

    • After you run the bundle target with ant bundle you will find MyJavaMacOSXApp.app in the /dist directory.

    What does the element?

    Inlining Oracle Java 7 Package (JRE)

    The Ant target above copies the Oracle Java 7 Package (JRE) from your

    • JAVA_HOME

    into

    • MyJavaMacOSXApp.app/Contents/PlugIns

    So the application package is totally self contained and does not need an Oracle Java 7 Package (JRE) installed on the target system at all. Like you can see in the following screen shot of such a deployed MyJavaMacOSXApp.app:

    MyJavaMacOSXApp Inline JRE

    Wiring default Oracle Java 7 Package (JRE)

    If you want to use the default Oracle Java 7 Package (JRE) installed on the application bundle target Mac under

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

    you have to remove the

    element fromt the bundle task. Like you can see in the following screen shot of such a deployed MyJavaMacOSXApp.app:

    MyJavaMacOSXApp Inline JRE

    Source of 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();
                }
            });
        }
    }
    

    What if my app has multiple jar files?

    Just add as many entries as you need.

    Note: The order of elements in the bundle task isn't preserved at runtime of your bundled app. The java.class.path gets built up at runtime by the native JavaAppLauncher as it reads in the *.jars from MyJavaMacOSXApp.app/Contents/Java directory.


    Just for completeness, this is how Info.plist looks like:

    
    
    
        
            CFBundleDevelopmentRegion
            English
            CFBundleExecutable
            JavaAppLauncher
            CFBundleIconFile
            GenericApp.icns
            CFBundleIdentifier
            com.example.MyJavaMacOSXApp
            CFBundleDisplayName
            My Java Mac OS X App
            CFBundleInfoDictionaryVersion
            6.0
            CFBundleName
            MyJavaMacOSXApp
            CFBundlePackageType
            APPL
            CFBundleShortVersionString
            1.0
            CFBundleSignature
            ????
            CFBundleVersion
            1
            NSHumanReadableCopyright
            
            LSApplicationCategoryType
            public.app-category.developer-tools
            JVMRuntime
            jdk1.7.0_17.jdk
            JVMMainClassName
            com.example.MyJavaMacOSXApp
            JVMOptions
            
            
            JVMArguments
            
            
        
     
    

    Important documents this answer is based on:

    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

    There is also a well maintained fork of appbundler itself, with many more features and bugfixes.

    • https://bitbucket.org/infinitekind/appbundler

提交回复
热议问题