35

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 output of java -version is showing 7.

I tried most of the things mentioned in different sites, but I was unable to fix this issue.

JAVA_HOME is also properly set.

I am using the Mac only for testing purposes. I really need some guidance on this.

When I run it with Eclipse by selecting JRE 7, it runs properly. Thus there is nothing wrong with the application. I am missing something on Mac OS X.

My Java system environment looks like this:

  • OS X version

    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 is not set

  • /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"
    

I guess my current JDK is pointing to something wrong.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
amod
  • 4,190
  • 10
  • 49
  • 75
  • how do you set JAVA_HOME. Keep in mind you normally have to 'export' the variable, otherwise it's only available to current shell instance – gerrytan Feb 11 '13 at 06:02
  • Also how do you execute the application? – Armand Feb 11 '13 at 06:04
  • @gerrytan its not in bash instance. I saved it in ~/.bash_profile. – amod Feb 11 '13 at 06:07
  • @Alison I did it in a user way... not from shell just by double click. – amod Feb 11 '13 at 06:08
  • Why not just run your application using the absolute path, e.g. /Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home/bin/java ? – Jintian DENG Mar 05 '13 at 11:31
  • @JintianDENG I am able to do it. But how to make sure that when user clicks on .app icon then it should run it using JAVA 7. I am able to use it using shell right now. – amod Mar 05 '13 at 13:37
  • All. Please help this question getting more attention. Even after giving the bounty its not getting the attention. – amod Mar 06 '13 at 18:40
  • There are several things that would be useful to know as well, because there changed a lot of things recently. 1.) Which OS X version do you use? 2.) What dumps the command `/usr/libexec/java_home -V` out? 3.) What dumps the command `/usr/libexec/java_home` out? 4.) What dumps the command `echo $JAVA_HOME` out? 5.) What dumps the command `echo $JAVA_ARCH` out? 5.) What dumps the command `/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version` out? 6.) What dumps the command `ls /Library/Java/JavaVirtualMachines` out? Please edit your question with the results. – Uwe Günther Mar 07 '13 at 00:55
  • 7.) Do you have a /Applications/Utilities/Java Preferences.app? – Uwe Günther Mar 07 '13 at 01:38
  • @amod0017 you know JAVA_HOME is all uppercase, not like you wrote Java_Home. – Uwe Günther Mar 07 '13 at 03:29
  • @UweGünther Added all the information required by you. Please help me out its really important. Also I dont have JavaPreferences.app however I heard that now the same task in done by System Preferences that is right now pointing to /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java – amod Mar 07 '13 at 08:42
  • @amod0017 Don't be worried about not to have /Applications/Utils/Preferences.app. It got retired by Apple while rolling out Apple's Java Mac OS X 2012-006. For details look here: http://docs.oracle.com/javase/7/docs/webnotes/install/mac/mac-preferences.html So that's not your issue. – Uwe Günther Mar 07 '13 at 09:43
  • @amod0017 can you please also post what the command `/System/Library/Frameworks/JavaVM.framework/Commands/java -version` dumps out. It can be be it isn't there at all, just tell me as well in this case. Please update your question regards this fact. BTW: could you pleas reformat the output of ` /usr/libexec/java_home -V` in your question like its printed out in the console (each JDK on a separate line). Thanks Uwe – Uwe Günther Mar 07 '13 at 09:48
  • @UweGünther I have formatted the o/p of the command as it appears on the console and also have added the other command's o/p. Please let me know it you require anything. Thanks a lot for the help and giving time :) – amod Mar 07 '13 at 10:00
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/25764/discussion-between-amod0017-and-uwe-gunther) – amod Mar 07 '13 at 10:06
  • @amod0017 So what are you exactly suffering from? As far as I understood your application is using Java 1.6.x instead of 1.7.x Am I right? How do you start it in case its starting with the wrong Java version? Do you start it as a proper `app` like `MyApp.app` or from the command line via `/usr/bin/java -jar ...`? – Uwe Günther Mar 07 '13 at 10:08
  • @UweGünther I am launching the application from MyApplication.app. At this time its using Java 6 instead of java 7. You are right its using 1.6.x. I am confused whats going wrong because when i launch it from command line `/usr/bin/java -jar` it uses Java 7. – amod Mar 07 '13 at 10:13
  • @amod0017 Are you sure about that? Can just do `System.out.println("java.version=" + System.getProperty("java.version"));` (or something similar) somewhere in your code and start the application as ` MyApplication.app` and tell me what it says. – Uwe Günther Mar 07 '13 at 10:18
  • @UweGünther I did it and its showing 1.6 :( – amod Mar 07 '13 at 11:17
  • @hertim Thnx for the edit :) – amod Mar 12 '13 at 06:39

5 Answers5

90

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

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

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 <project>/lib/appbundler-1.0.jar
  • Add the following to your <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>
    

    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 <project>/dist directory.

What does the <runtime dir="${env.JAVA_HOME}" /> 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

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

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 <classpath file="dist/additional.jar" /> 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:

<?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> 

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.

Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
Uwe Günther
  • 2,971
  • 2
  • 21
  • 26
  • Using App Bundler will it create a single jar for the whole application. I have multiple jars in my project and I want them separated? – amod Mar 08 '13 at 18:58
  • BDW I am really thankful to you for your continuous efforts on solving this problem :) – amod Mar 08 '13 at 19:00
  • 2
    @amod0017 I changed the answer post. You can find it under 'What if my app has multiple jar files?' Oracles AppBundler will preserve all your `*.jar`s in the 'MyJavaMacOSXApp.app/Contents/Java' directory. I hope this answer was helpful for you and if you think this is the answer to your issue I would appreciate it if you flag this answer post as the answer to your question (green tick). – Uwe Günther Mar 08 '13 at 23:42
  • Just last few questions. I am using installanywhere for creating the .app file. Can you give some pointers to it please. – amod Mar 11 '13 at 12:28
  • 1
    @amod0017 With the standard way described here in this post and suggested by Oracle for doing application packages for Java 7 on Mac OS X 10.7.3+ you have now a *.app package. Just stick this application package in a standard Mac OS X disk image (aka *.dmg file) and ship it to the customer. Details can be found here: http://stackoverflow.com/questions/96882/how-do-i-create-a-nice-looking-dmg-for-mac-os-x-using-command-line-tools – Uwe Günther Mar 11 '13 at 13:35
  • here you go man for all your efforts you have the bounty before it expires... To be very honest this is not a perfect answer I was looking for. There are lots of things involved but I will be working on the things you told me and will be keeping you updated. But you truly deserves this bounty because you helped me a lot. Please give me your email id so that I can ask you something if required. – amod Mar 11 '13 at 19:04
  • 1
    @amod0017 I appreciate the bounty and the answer tick! Looks like your problems could fill a chapter in a book about Java development on Mac OS X. Nevertheless I think if you create an application package how it is described here - you are in good shape to to go on to build a dmg file for deployment to the end user. My email is public in my profile since day one. Just check if you can find it there if not let me know. – Uwe Günther Mar 12 '13 at 09:23
  • 2
    @lance-roberts Thanks for your efforts fixing the typos in my post. I like reviews, especially if the go this way. – Uwe Günther Mar 12 '13 at 09:26
  • @UweGünther the `.app` bundle generated by this process does not take argument from command line. When i run this command `open MyJavaMacOSXApp.app --args arg1 arg2 arg3 arg4` it opens application but argument does not goes to application's `main` function. why ??? is there any solution for this ? – Mukesh Kumar Singh Mar 07 '14 at 06:46
  • @UweGünther take a look my question here, http://stackoverflow.com/questions/22218375/swt-application-not-acception-argument-from-command-line, please answer this if you can. – Mukesh Kumar Singh Mar 07 '14 at 06:49
  • This is a great very thorough answer. As an improvement I suggest pointing to a well maintained fork of Appbundler with many more options and bugfixes here https://bitbucket.org/infinitekind/appbundler – simmerman Jul 17 '14 at 02:06
  • @UweGünther thanks for your answer, how about Maven based projects? – Jack Jan 29 '15 at 05:09
  • 1
    Upon trying these steps in Mac OS X Yosemite, I get this error: BUILD FAILED NetBeansProjects/MyJavaMacOSXApp/build.xml:89: java.nio.file.NoSuchFileException: NetBeansProjects/MyJavaMacOSXApp/Info.plist Should there be an Info.plist file somewhere? – ziggurism May 29 '15 at 23:21
4

The Java version required by the app is probable specified in the application's metadata. If you right-click on the app and select Show Package Contents and browse to the Info.plist file, you should find entries which define the JVM that the application will use. E.g.

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

OSX may choose to use a lower JVM if the application requests it.

Armand
  • 23,463
  • 20
  • 90
  • 119
  • Yes there was 1.4+ in the info.plist. After making it 1.7; its giving me an popup no compatible version of Java 1.7. However java -version command is properly working. – amod Feb 11 '13 at 06:22
  • adding further. It is requesting to set Java Preferences but since I reinstalled java I am unable to get tht option (apple removed it). Please let me know if sumhing is possible – amod Feb 11 '13 at 08:30
  • @amod0017 According to http://developer.apple.com/library/mac/#documentation/Java/Reference/Java_InfoplistRef/Articles/JavaDictionaryInfo.plistKeys.html#//apple_ref/doc/uid/TP40001969, you may change it to 1.6+ and give it a try. – Jintian DENG Mar 05 '13 at 14:02
  • I made it 1.7 it didnt worked. Please check my previous comments. – amod Mar 06 '13 at 12:18
  • 1
    @sixlettervariables Like I mentioned in my answer there are 2 different native `JavaAppLaunchers`, one from Apple aka `Jar Bundler`, which is working with Apples Java System Packages only. The latest one from Apple is 1.6.0_43, there will be _no_ one for Java 7. And the other one is from Oracle, aka as the `AppBundlerTask`, which is working with Oracle Java System Packages only. The earliest Java version from Oracle really working with Mac OS X 10.7.3 and above was 1.7.0_04. I hope this removes any ambiguity and doubts.In addition to the 2 official one, there are some 3rd party approaches out. – Uwe Günther Mar 12 '13 at 09:54
4

Your system isn't really up to date. I am not saying this is causing your issue. But just to be on the safe side I would role forward to the latest and greatest.

  1. Role your system forward via System update, that you are on Mac OS X 10.8.2
  2. Install a fresh JRE 1.6.0_43 from Apple aka Java for OS X 2013-002
  3. Install a fresh JDK 1.6.0_43 from Apple aka Java for OS X 2013-002 Developer Package Mar 4, 2013. In order to get the Apple JDK you have to login here with your Apple ID (free Developer Account) and search for the term "Java for OS X 2013-002 Developer Package". Unfortunate there is no direct link for that package.
  4. Delete your outdated Oracle JDK: sudo rm -rf /Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk. Note: Thats safe because in the next step we are installing the current Oracle JDK 1.7.0_17.
  5. Download and install Oracle JDK 1.7.0_17 for Mac OS X. Note: This does also include the JRE 1.7.0_17 from Oracle.
  6. Do a reboot.

After you have finished all steps from above, please come up with the following output again:

  1. Which OS X version do you use?
  2. What dumps the command /usr/libexec/java_home -V out?
  3. What dumps the command /usr/libexec/java_home out?
  4. What dumps the command echo $JAVA_HOME out?
  5. What dumps the command echo $JAVA_ARCH out?
  6. What dumps the command /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version out?
  7. What dumps the command ls /Library/Java/JavaVirtualMachines out?
  8. What dumps the command /System/Library/Frameworks/JavaVM.framework/Commands/java -version out?

Just document the steps and the effort you did in your original question. So it reflects your progress.

UPDATE: The solution is to create a Mac OS X application bundle with Oracles AppBundlerTask. For details see my other answer here: https://stackoverflow.com/a/15271448

Community
  • 1
  • 1
Uwe Günther
  • 2,971
  • 2
  • 21
  • 26
1

EDIT: Uwe's impressive answer is absolutely correct for the OP who it turns out was using the AppLauncher. My initial read of the question was that it related to command-line issues on OSX with Java 6 vs Java 7. The comments on the original question show I was wrong. However, anyone having command-line issues may find the below a simpler solution.

ORIGINAL: My circumstances seemed the same as I thought the OP had: Java 1.7 perfectly on the command-line but mvn failing and complaining about 1.6, general compilation had been working fine using sbt and IntelliJ. I only started having problems compiling a third-party project with mvn.

I found this to work well and be much simpler:

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

All I needed from that was the following in .profile:

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

Set that variable and mvn worked well.

Andrew E
  • 7,697
  • 3
  • 42
  • 38
  • 1
    The original poster had an issue with using the Apple AppLauncher for Oracle Java within its own Application bundle. This has nothing to do with using the java command line stub for kicking of maven via mvn on the command line. – Uwe Günther Sep 04 '13 at 13:12
  • 1
    @UweGünther, you are, of course, correct. But for viewers reading only the OPs question (i.e. not the comments following it), as I did when landing on the question from a Google search, it's reasonable to conclude the issue is a command-line problem and not the larger issue you identified and solved. I want to save those readers the time of going down the application plist rabbit hole to no avail, as I did. – Andrew E Apr 14 '14 at 14:43
1

Try installing this:

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

InteliJ works just fine, while I'm still on Java SE 7 using for example NetBeans.

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)
candylady
  • 57
  • 1
  • 9
  • I have a 3rd party app that wont work in El Capitan after upgrading. This solution above makes it work in El Capitan now. I would rather have it working properly with the new Java version but this will do :) – Ketan Oct 03 '15 at 02:13