tofi86 / universalJavaApplicationStub

universalJavaApplicationStub - an alternative Application launcher script for Java based macOS Apps that works with both Apple's and Oracle's PList format and supports the old Apple Java 6 as well as all the latest Oracle/OpenJDK/Adopt/Corretto JRE's/JDK's. Plus it supports drag&drop to the Dock icon 🎉
MIT License
356 stars 168 forks source link

OS X Yosemite still asks to install JRE 6 #9

Closed thebiguno closed 9 years ago

thebiguno commented 9 years ago

Hello,

I have recently found this project when researching a problem reported by users, that OSX Yosemite will request the install of JRE 6 when running my application. Your script sounds like it would fix things, however I am still seeing the same issue. Digging further, it appears that OS X is intercepting the app bundle execution even before passing control to your script. (To verify this, I added a line 'echo "foo" > "~/bar.txt"', and it doesn't appear when double clicking on the application, but if I run the script directly from the command line, the file appears and the app launches properly).

If I remove the "Java" tag in the Info.plist file, your script is executed (and then complains about a missing main class, as expected). So, it appears to me that OSX is intercepting execution before the JavaApplicationStub is executed, IF there is a "Java" key in the Info.plist.

(For the record, I am using the latest version of JarBundler ant task - 2.3.1 - and it appears to be writing Info.plist in the Apple format. I have installed the latest JRE from Oracle - 8 update 25.)

Have you seen this problem before? Any thoughts on what I can try next? I'm sure that I can get it working by hacking your script plus the Info.plist file, but I would like to keep things as close to normal as possible (for whatever constitutes 'normal' in the ever-changing landscape of Apple / Java relations!)

Any thoughts on this would be greatly appreciated.

Cheers

thebiguno commented 9 years ago

As an update, I did find that if I rename the key "Java" to "JavaX", and then replace every section in your script that refers to key ":Java" with ":JavaX" (i.e. in the section where you find what PList version we are using and where you extract the keys from the Apple version) then it works exactly as it should. So, it is obvious that whatever Mavericks is doing, it is switching on the Java key in Apple formatted Info.plist files to do its thing.

I have my changes integrated into my ant task (I use a 'replace' task to rename the Java key to JavaX, and I have manually changed your script to match), so there is no ongoing maintenance needed. I would consider this to be a successful workaround, as far as 'just getting it done' is concerned. However I would love to hear if others have had this same problem, and how they have resolved it. I can't be alone in this issue, and if there is a better way to do this, I am all ears!

(In case anyone is interested, the project in question that I am doing this for is Buddi - http://buddi.digitalcave.ca/ )

Cheers

mbtaylor commented 9 years ago

@thebiguno, I tried this project out and it didn't work for me - likely I was running into the same problem that you saw. Just to confirm you're not alone! Up till now I haven't found a workaround. I will see if I can get what you suggest working, though it's not easy for me to test stuff since I don't have easy access to any Macs (I'm developing multiplatform code for third parties).

tofi86 commented 9 years ago

Wow, thanks for the research, @thebiguno ! I've recently had a bug report with these symptoms, but couldn't reproduce it on Yosemite with Oracle Java 7.

Until now I never had any trouble using my Java stub with Java 7. But if this issue is getting bigger, what possibilities do we have to support both Apple Java 6 and Oracle Java 7/8 with one generic plist file? Another plist structure only for this project / stub file? don't like the idea very much...

I'll definately digg deeper into the stuff in the next couple of weeks. Very busy at the moment. Solutions and discussion very welcome! :smile:

tofi86 commented 9 years ago

Note to myself: Feedback from another user with the same issues:

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (2):
    1.8.0_05, x86_64:   "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home
    1.7.0_51, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home
$ open -a EPUB-Checker
LSOpenURLsWithRole() failed for the application /Applications/EPUB-Checker.app with error -10658.
RaiMan commented 9 years ago

Since I am really happy with this neat solution, because it helped me to bring back the Mac application to my users of SikuliX (http://sikulix.com and https://github.com/RaiMan/SikuliX-2014), I want to talk about my approach, that works with Java 7, 6 and 8 on OS X 10.7 to 10.10.1:

This is it:

<?xml version="1.0" encoding="UTF-8"?>
<!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>en_US</string>
    <key>CFBundleExecutable</key>
    <string>JavaAppLauncher</string>
    <key>CFBundleIconFile</key>
    <string>sikulix.icns</string>
    <key>CFBundleIdentifier</key>
    <string>com.sikulix.SikuliX</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>SikuliX</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.1.0</string>
    <key>CFBundleDocumentTypes</key>
    <array>
      <dict>
        <key>CFBundleTypeExtensions</key>
        <array>
          <string>sikuli</string>
          <string>skl</string>
        </array>
        <key>CFBundleTypeIconFile</key>
        <string>sikulixsrc.icns</string>
        <key>CFBundleTypeName</key>
        <string>SikuliX script file</string>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
        <key>LSTypeIsPackage</key>
        <true/>
      </dict>
    </array>
    <key>JVMMainClassName</key>
    <string>org/sikuli/ide/SikuliIDE</string>
    <key>JVMOptions</key>
    <array>
      <string>-Dfile.encoding=UTF-8</string>
      <string>-Dsikulix.asapp</string>
      <string>-Xmx512M</string>
    </array>
    <key>JVMArguments</key>
    <array/>
  </dict>
</plist>
mbtaylor commented 9 years ago

So, yes by avoiding use of the key "Java" it appears to work for all the combinations of OSX and java installations that I've been able to get people to try. I'll probably stick with this, unless I find it's not working in some cases. However if I understand what's going on correctly, using this solution the (renamed) java-specific parts of the Info.plist file aren't doing much useful work - it would probably be cleaner to hard code the details of the java launching code in the "stub" script instead of burying them in the plist file under a custom key and pulling them out again using PlistBuddy.

I'll keep an eye on this project in case a cleaner solution emerges - in any case, thanks for writing something that explains what the application bundle is doing in a way that gives me a chance to work round it!

thebiguno commented 9 years ago

You are probably right that it would be cleaner in a different way; however by renaming Java to JavaX you can keep your existing build scripts the same (in my case, the use of the bundle jar ant task) and just make a single line replacement after the fact. Other than that, there is not really any advantages that I can think of.

Dylan-M commented 9 years ago

From a naive look, this appears to be the exact same issue I solved here. All of the symptoms I encountered matched yours, especially being able to launch from the script via command line but not double clicking the app.

thebiguno commented 9 years ago

Thanks for the comment! However I think that the problem is a bit different... the problem I was experiencing was that the universalJavaApplicationStub program was not even being executed; the OS would just execute the Java program with some default JRE, without referencing my startup program at all. By changing the tag in the .plist file to (or anything other than Java), then the startup script would be executed.

I apologize if I mis-read your issue, though.

Cheers

Dylan-M commented 9 years ago

Well, mine was actually a combination of 2 different issues, the one I linked to, and then also one that Tobias just fixed, but as you say yours does appear to be different. Still, it can't hurt to try a file with both of the fixes for those 2 issues stuck in there. It could be that OSX is doing something funky purely because of the breakage. For example, your echo test I wouldn't consider valid, since I tried the exact same thing and had the exact same result as you, but my fixes "fixed" that as well.

That said, it wouldn't surprise me in the least if Apple did something stupid with Yosemite, since the highest I tested on was Mountain Lion.

tofi86 commented 9 years ago

At the moment, I don't have my companies dev mac around with Yosemite and without Java 6, so I'd like you to test the stub file in version 0.8.0 which I released a few minutes ago.

v0.8.0 fixes several issues – one of which is the support for the JVMVersion key which @Dylan-M says would also fix the Yosemite JRE6 issue. So go, add a JVMVersion key in your Apple style Plist file (with at least 1.6+) and give it a try and report back to me! :)

Cheers, Tobias

Dylan-M commented 9 years ago

Just for CYA, I hope it fixes it ;)

I haven't yet received any testing results from users of Mavericks or Yosemite on my project though.

Dylan-M commented 9 years ago

And, no sooner did I post the above CYA than I got this response from a user:

Running on Yosemite 10.10.1, Java 8u31 Everything runs smoothly. Thanks for the changes, ralgith!

  • GreekFire
tofi86 commented 9 years ago

Great! So adding a JVMVersion key

      <key>JVMVersion</key>
      <string>1.6+</string>

and using universalJavaApplicationStub version 0.8.0 should finally fix this. Going to test it tomorrow as well :sunglasses:

tofi86 commented 9 years ago

Well, In my case, on my companies dev machine, the java 7 installation isn't listed in /usr/libexec/java_home -V at all! Therefore the solution to add JVMVersion key and using v0.8.0 doesn't help for me.

If I run the script on the commandlien, the else fallback is used and my apps work well, but starting by double clicking the app icon still fails with the old "JRE 6" message.

Renaming the Plist key Java to something else seems to be the only solution at the moment which works well...

Dylan-M commented 9 years ago

Well, that's odd... something went wonky with your install of /usr/libexec/java_home doesn't list it at all. Maybe installed as a "per user" thing, rather than system wide?

tofi86 commented 9 years ago

Yep, that's weird.... bildschirmfoto 2015-02-23 um 16 07 44

Installed both JRE 7 and JRE 8 now, but I'm not able to install both versions parallel and neither of them creates an entry in /usr/libexec/java_home. Installed for all users on this machine - this is the only option provided by the Oracle JRE installer. My System is Yosemite 10.10 without(!) Apple Java 6 installed...

At http://apple.stackexchange.com/a/160216 they say, this is because /usr/libexec/java_home only searches for JVM's at the "old" location, not at the new Oracle location.

On the other hand I have Mac systems with Apple JRE 6 and Oracle JRE 7 where both versions are listed in /usr/libexec/java_home... So odd...

tofi86 commented 9 years ago

Alright, so I installed the JDK 8 now in a last attempt to solve this issue, and here we go:

iMac:~ pagina$ /usr/libexec/java_home -V
Matching Java Virtual Machines (1):
    1.8.0_31, x86_64:   "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home

However, no "normal" user would install the JDK - they will get pointed to the JRE by Oracle...

Also, this JVM get's picked up by the universalJavaApplicationStub v0.8.0 and can be used to start the application via command line. However, opening the app by the normal way still fails.

So this issue really seems to be related a 100% to the Java Plist key! Why o why, Apple... :disappointed:

Dylan-M commented 9 years ago

Actually, per Oracle's own documentation you have to install the JDK for anything other than web usage. That explains a lot though.

tofi86 commented 9 years ago

Actually, per Oracle's own documentation you have to install the JDK for anything other than web usage. That explains a lot though.

Yes, it does... But most people will only install Java from java.com, so using the standard JRE... :-/ Also, the JDK isn't solving the "old Java 6" problem Apple is fooling us with...

Dylan-M commented 9 years ago

Well, don't even get me started on Apple dropping official support for Java and all the issues that has caused... I don't think you want a half informed tirade [half cause I develop for Apple, but don't own one]

ostefano commented 9 years ago

Same thing here. universalJavaApplicationStub runs ok from the command line, but double clicking brings up the pesky "Install Java 6". Only VM installed is Oracle 1.8.31.

Dylan-M commented 9 years ago

Are you guys trying to latest official code? Cause regarding aleth's comment, it should be JVMVersion, not JMVersion. The easiest way to get the correct functionality is to use the latest code instead of hand editing your own. This will prevent simple mistakes such as typos and the like.

ostefano commented 9 years ago

Yes, I am using the latest code.

Dylan-M commented 9 years ago

@aleth Okay, your post-reboot functionality is what should be happening for the issue with the current code. Thanks.

Dylan-M commented 9 years ago

@aleth Umm, yeah, you're suppsed to be using 1.7+, not 1.6+. Obviously it'll look for a 1.6 JVM if you tell it that's what version you want.

tofi86 commented 9 years ago

1.6+ should actually match ANY JVM higher than or equal to 1.6 listed in /usr/libexec/java_home, shouldn't it? That can't be the problem...

Dylan-M commented 9 years ago

@tofi86 It should, but obviously doesn't. I haven't yet figured out why. It's... flaky. Of course, it should really be your_min_version+ anyway. So if you compile against 1.6, then yes, 1.6 is appropriate I guess. Except for not working right in the detection of course.

tofi86 commented 9 years ago

@aleth: what does /usr/libexec/java_home -V (capital V) print out in your case?

And what is the result for

/usr/libexec/java_home -v 1.6+

And for

/usr/libexec/java_home -v 1.7+
Dylan-M commented 9 years ago

@aleth I'm guessing you've only installed the "JVM", you have to install the "JDK" for full functionality. As @tofi86 and I discussed above. Only the JDKs include full versions. The Oracle JVMs for Mac only include the "browser plugin" version. And while it'll run Java programs, it doesn't get picked up by Mac correctly.

tofi86 commented 9 years ago

Not entirely true, Dylan. The Internet plugin should get picked up by my stub file. But I think a bug in v0.8.0 prevents it to be picked up in this special case when there are no entries in /usr/libexec/java_home but a JVMVersion string is found... Will be fixed tomorrow or soon... ;-)

Dylan-M commented 9 years ago

@aleth Ah, I had missed that. But, sounds like Tobias has it well in hand, and my experience with OSX is admittedly quite limited.

@tofi86 Ah, I had forgotten you added special case detection for the JRE plugin. But, I'm glad you figured it out ;)

tofi86 commented 9 years ago

@aleth: alright, this issue should be fixed now in v0.8.1 please test and post a short feedback.

However, this still doesn't solve the nasty "install JRE 6" Apple "bug"...

llbit commented 9 years ago

I'm trying to use this on Yosemite with Oracle JDK 1.8.0_40 stub 0.8.1, and get the "install JRE 6" when launching the app using Finder. When launching from a terminal it works. Seems like the stub is not executed?

Edit: I was using jarbundler.

bschooly commented 9 years ago

I too have the same issue with 1.8. I've read the entire thread and still don't know if there is a resolution or not. If so could someone distill this for me.

thebiguno commented 9 years ago

If you follow my instructions in the second post from this thread, it should work (it does for me and all my users, at least). I don't know if the author has any definite fixes (there seem to be some that say it works with the new version, while others are still having problems). I have not had time to re-investigate the issue, and I have not heard of any users for which my workaround does not fix the issue, so I have no urgency to look into it further.

I realize this is not a definitive post, but I can only say what has worked for my and my software.

Cheers

bschooly commented 9 years ago

I'm using jarbundler. How do I get it to output JavaX to the plist file?

thebiguno commented 9 years ago

I use ant with a 'replace' tag after the Info.plist file is created. See http://git.digitalcave.ca/gitweb/?p=java/ca.digitalcave.buddi.git;a=blob;f=build.xml;h=ded5de33dafcadb2aa517ee57a0eb9ee426d7cd7;hb=HEAD line 149-152 for my ant script.

Cheers

tofi86 commented 9 years ago

No solution yet within the scope of this project...

Probably I should take the time and create another fork of the jarbundler project for creating JavaX-Keys. However, I'm still struggling a little bit with this solution as we're creating our own environment again instead of being able to use the "standards"... Though the standards don't work, yeah, I know... :-/

thebiguno commented 9 years ago

IMHO forking jar bundler is not worthwhile... it is a four line addition to an ant script to do this automatically. Does anyone not use ant (or some other automated build script) these days?

I do agree that it would be nice if we didn't need to do this at all, but Apple seems to have effectively prevented that from happening :-(

tofi86 commented 9 years ago

Alright, this journey finally has come to an end!

Today, I forked Informagens jarbundler (once again) and added an optional boolean argument useJavaXKey. If set to true, the Java dictionary key will no longer be named Java but JavaX.

Example:

<jarbundler
    ...
    stubfile="universalJavaApplicationStub"
    usejavaxkey="true"
    ...
>

You can download the package here: https://github.com/tofi86/Jarbundler/releases/tag/v2.4.0

I also had to change the universalJavaApplicationStub to support the JavaX Plist key, so you have to check out the latest version 0.9 to use it with JarBundler 2.4

Have fun! :sunglasses:

userbrett commented 8 years ago

Hi,

Tried universalJavaApplicationStub for the first time today after upgrading to 10.11.1 - El Capitan. Seeing the same sort of things. Am not using JarBundler or AppBundler, just plain old javac and jar. As Apple seems to have my app wedged too, thought I'd contribute what I'm seeing in hopes that there's a solution.

Using universalJavaApplicationStub v1.0.1, 2015.11.2

For a check, I have universalJavaApplicationStub printing a "running..." line to a file when it is executed - it's never being called when starting the app via 2x-click.

In all instances below:

Am using Apple Info.plist containing:

<key>JavaX</key>

With only JRE8 installed:

Running /usr/libexec/java_home shows no java. Running universalJavaApplicationStub via CLI - the app runs as an OS X app. 2x-clicking the App/icon prompts for the legacy Apple Java 6.

With JRE8 and JDK8 installed:

Running /usr/libexec/java_home shows /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home 2x-clicking the App/icon prompts for the legacy Apple Java 6.

Advice/suggestions are greatly appreciated. Thanks.

tofi86 commented 8 years ago

Working fine for me on El Capitan.

Can you post your full Info.plist file?

userbrett commented 8 years ago

Sure! Thanks for asking/helping.

<?xml version="1.0" encoding="UTF-8"?>
<!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>universalJavaApplicationStub</string>
        <key>CFBundleIdentifier</key>
        <string>com.mydomain.myapp</string>
        <key>CFBundleName</key>
        <string>myapp</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleIconFile</key>
        <string>myapp</string>
        <key>JavaX</key>
        <dict>
                <key>ClassPath</key>
                <array>
                        <string>$JAVAROOT/myapp.jar</string>
                </array>
                <key>JVMVersion</key>
                <string>1.6+</string>
                <key>MainClass</key>
                <string>com.mydomain.myapp.Main</string>
                <key>SplashFile</key>
                <string>$JAVAROOT/myapp.png</string>
                <key>Properties</key>
                <dict>
                        <key>apple.laf.useScreenMenuBar</key>
                        <string>true</string>
                </dict>
                <key>WorkingDirectory</key>
                <string>$APP_PACKAGE/Contents/Resources/Java</string>
        </dict>
        <key>LSHasLocalizedDisplayName</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
        <string>Copyright (C) 2009-2015 My Name, All Rights Reserved.</string>
</dict>
</plist>
Dylan-M commented 8 years ago

Perhaps your issue is this? :)

JVMVersion
            <string>1.6+</string>
tofi86 commented 8 years ago

Can you post the terminal output of the following four commands, please?

/usr/libexec/java_home -V
/usr/libexec/java_home -v 1.6+
/Library/Java/Home/bin/java -version
/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version

@Dylan-M wrote:

Perhaps your issue is this? :) JVMVersion 1.6+

This shouldn't be a problem if Java 6 or higher is installed. /usr/libexec/java_home -v 1.6+ should always pick up the highest matching JVM available.

userbrett commented 8 years ago

Absolutely. Thanks for the help!

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (1):
    1.8.0_65, x86_64:   "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home
$ /usr/libexec/java_home -v 1.6+
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home
$ /Library/Java/Home/bin/java -version
-bash: /Library/Java/Home/bin/java: No such file or directory
$ /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)

and FWIW:

$ ls /Library/Java/ 
Extensions      JavaVirtualMachines
tofi86 commented 8 years ago

I cannot find an error in your configuration. This should work fine.

Is the universalJavaApplicationStub file marked as executable?

Is there a console output when you run the stub like this?

$ cd your/app/directory/
$ ./myapp.app/Contents/MacOS/universalJavaApplicationStub
userbrett commented 8 years ago

Thank you for confirming the configuration. Yes, the universalJavaApplicationStub is executable. Executing as you indicated resulted in a repeatable system error. The error produced a report that kept pointing to the same area of memory, and gave other indicators that online articles indicated that the memory was suspect. I've Amazoned a #00 phillips screwdriver, and when it arrives I'll see if there is removable RAM that can be swapped / re-seated.

In the meantime, I created a smaller/simpler jar file, and swapped out the larger failing one with the smaller one - and the smaller one starts every time using universalJavaApplicationStub by 2x clicking the application.

Also, I managed to print out to the console the "Java startup command" that universalJavaApplicationStub was executing. Manually executing that exact command, the larger (failing) application started up perfectly. So, another confirmation point that universalJavaApplicationStub is working just fine.

Sadly, I ended up breaking Apple's Java symlinks and other Java magic, enough to the point that this machine is also going to need to be re-imaged.

Tobias, thank you very much for creating universalJavaApplicationStub, and also for supporting those of us who want to use it.

Dylan-M commented 8 years ago

@fubar4 In the future you may want to manage installed versions of Java on Mac using Homebrew + Jenv. In fact, you probably could salvage the existing install by doing this, I know I did.

http://www.codingricky.com/jenv/

Homebrew is a wonderful tool in general, especially for someone like me who is primarily a Linux user and only does a Mac for testing purposes and currently also at work.