Home > Java, Mac administration, Mac OS X, Scripting > Modifying Oracle’s Java SDK to run Java applications on OS X

Modifying Oracle’s Java SDK to run Java applications on OS X

As part of releasing the developer betas for OS X 10.11, Apple announced that El Capitan would be the end of the line for the Java 6 runtime and tools provided by Apple, with the clear statement that developers should be moving on to Oracle’s Java tools.

To completely replace Apple’s Java 6 tools, Oracle’s Java JDK (Java SE Development Kit) will need to be installed. This is because the Oracle Java JRE (Java Runtime Environment) on OS X is a browser plug-in for running Java via a web browser and does not include capabilities for running Java desktop apps or command line tools.

By default though, the Oracle JDK does not set several options to advertise the capabilities provided by the JDK to Java apps, which may cause applications that need those capabilities to fail to launch. The capabilities are actually present in the JDK, but those options need to be set before applications will recognize them as available.

To fix this, we need to add the following options to Oracle’s Java JDK:

  • BundledApp
  • JNI

 In turn, enabling these options means they need to be added to the list of JVMCapabilities stored in the following plist file:

/Library/Java/JavaVirtualMachines/jdk_version_info_goes_here.jdk/Contents/Info.plist

Screen Shot 2015 08 08 at 7 39 19 AM

For more details, see below the jump.

Michael Lynn has developed a Python script for adding the necessary BundledApp and JNI options to the Info.plist file referenced above.


Update – 8-11-2015: Mike has updated his script to provide better compatibility for OS X Java applications to be run via Oracle’s Java JDK. He’s posted a blog entry with the details here:

http://michaellynn.github.io/2015/08/10/even-more-oracle-java-compatibility/

He was kind enough to update the Github gist linked to this post, so the script displayed below is the updated version. I’ve also updated the script and payload-free package available from my Github repo.



#!/usr/bin/python
import plistlib, os.path, os
# Based off of https://forums.developer.apple.com/message/6741
# and http://apple.stackexchange.com/a/136976
def jdk_info_plists():
# Find all the JDK Info.plist files
JDK_ROOT = "/Library/Java/JavaVirtualMachines"
if (os.path.exists(JDK_ROOT) and os.path.isdir(JDK_ROOT)):
# It's present, let's look for installs
for file in os.listdir(JDK_ROOT):
jdk_dir = os.path.join(JDK_ROOT, file)
if (os.path.isdir(jdk_dir)):
# Check for Info.plist
info_plist = os.path.join(jdk_dir, "Contents", "Info.plist")
if (os.path.isfile(info_plist)):
yield info_plist
for info_plist in jdk_info_plists():
# Change all the plists of all the installed JDKs
info = plistlib.readPlist(info_plist)
# Convert the capabilities into a set
capabilities = set(info['JavaVM']['JVMCapabilities'])
capabilities.add('JNI')
capabilities.add('BundledApp')
# Update our changes
info['JavaVM']['JVMCapabilities'] = sorted(capabilities)
# Write back our changes
plistlib.writePlist(info, info_plist)
# Create a symlink to fix legacy applications
# Find the Contents directory
contents_path = os.path.dirname(info_plist)
# make the bundle/Libraries subpath
bundle_libraries = os.path.join(contents_path, "Home", "bundle", "Libraries")
try:
# Just in case you run this script multiple times, we'll fail if the directory already exists
os.makedirs(os.path.join(bundle_libraries))
except:
pass
# create the symlink between libjvm.dylib and libserver.dylib
libjvm_dylib = os.path.join(contents_path, "Home", "jre", "lib", "server", "libjvm.dylib")
libserver_dylib = os.path.join(bundle_libraries, "libserver.dylib")
try:
# Just in case you run this script multiple times, we'll fail if the file already exists
os.symlink(libjvm_dylib, libserver_dylib)
except:
pass

view raw

modify_java.py

hosted with ❤ by GitHub

When this script is run, it will update all of the Java JDKs stored in /Library/Java/JavaVirtualMachines with the required options.

Before

Screen Shot 2015 08 08 at 7 40 33 AM


After

Screen Shot 2015 08 08 at 7 42 57 AM

 

Once the BundledApp and JNI options are added, Java applications should be able to start using the JDK’s capabilities in order to launch and run. In my own case, I verified this by running ImageJ, an open-source Java-based image processing program, on a machine where Oracle’s Java 1.8.0_51 (also known as Java 8 Update 51) JDK has been installed and updated with the BundledApp and JNI options referenced above.

Screen Shot 2015 08 08 at 7 50 09 AM

 

Screen Shot 2015 08 08 at 7 50 31 AM

I’ve posted Michael’s script to my GitHub repo at the following address:

https://github.com/rtrouton/rtrouton_scripts/tree/master/rtrouton_scripts/update_oracle_java_jdk_jvmcapabilities

This script is also available as a payload-free installer package, stored as a .zip file in the payload_free_installer directory.

  1. BP
    September 8, 2015 at 12:13 pm

    Does the following fix only work on 10.11? I tried it on OS X 10.10.4 and I see the script actually make the change, but I am still unable to launch either ImageJ or Minecraft. I get prompted to download Java 6 instead.

  2. September 9, 2015 at 10:14 am

    I am glad to see the post. Thanks for sharing an informative post.

  3. March 13, 2017 at 9:15 pm

    Any idea why the JNI capability was not enabled? Thanks!

  1. No trackbacks yet.

Leave a comment