UniFi Controller on MacOS fails to start

Issue description

When trying to launch the app, I get an error of Unable to load Java Runtime Environment:

unifi-controller-cannot-load-java-jre01

This is after upgrading from an older version. The UniFi team’s response is:

We stopped bundling Java as of UniFi Network 5.11.47. If you’re installing that release or later please make sure you have manually installed a current release of Java 8 beforehand. Only the Java Runtime Environment (JRE) is required. Oracle JRE 8 offers the simplest path as it will simply “just work” without requiring any changes. We may investigate alternative JVMs and update this message accordingly.

Which boils down to:

  • Java 8 is required for the controller
  • they stopped bundling Java 8 in the MacOS controllers since 5.11.47
  • Java 9 or newer is not supported

They ask you to go to https://www.java.com/en/download/ and download the Oracle JRE. At the time of this writing:

Recommended Version 8 Update 281 (filesize: 80.67 MB)
Release date January 19, 2021

Requiring Oracle Java is a mistake for business users, or any commercial use that requires Oracle Java. When Oracle changed the licensing model for Java, the licensing cost and compliance costs for business / commercial users got very expensive.

There are good and better Java distributions, including OpenJDK, AdoptOpenJDK and Amazon AWS Corretto.

OpenJDK 11 and OpenJDK 8 are the current long-term support releases. Requiring Oracle Java 8 is a mistake. If there is a technical reason in the Unifi implementation that somehow requires Oracle Java, that’s even more concerning.

1000s or 10000s of companies have already moved to OpenJDK or Corretto to avoid the licensing costs of Oracle Java. There is no advantage to using Oracle Java. OpenJDK is source-code compatible, and Corretto incorporates bug fixes and performance enhancements in addition to being compatible.

Solution 1

Start with installing Homebrew following the instructions on https://brew.sh/ and install a Java version you like, e.g.:

$ brew install corretto8 # or openjdk@8 or adoptopenjdk8

Then install the start-up script ~/bin/unifi.sh (also works with any other Java 8):

#!/bin/bash

###
#   Start the Unifi Launcher App with an alternative JDK
#   because Ubiquity fucked it up with Oracle's JDK
#   INFO:
#   https://community.ui.com/questions/Unifi-Controller-5-11-50-on-Mac-OS-X-Catalina-fails-to-start-/2fde6f63-b0ac-43a0-83f7-5cf43ba3d40f?page=1
###

SCRIPT_NAME=$(basename $0)
LOCK_FILE="/tmp/${SCRIPT_NAME%.sh}.lock"
UNIFI_LAUNCHER="/Applications/UniFi.app/Contents/Resources/lib/ace.jar"

_info() {
  MY_MESSAGE=${@}
  echo -e "$(/bin/date) ${SCRIPT_NAME} $$ INFO: ${MY_MESSAGE}"
}

_error() {
  MY_MESSAGE=${@}
  echo -e "$(/bin/date) ${SCRIPT_NAME} $$ ERROR: \
  could not execute: ${MY_MESSAGE}"
  exit 1;
}

# set a lock file.
if ( set -o noclobber; echo "$$" > "${LOCK_FILE}") 2> /dev/null ; then
  trap 'rm -f "${LOCK_FILE}"; exit $?' INT TERM EXIT
else
  _error "Another instance of ${SCRIPT_NAME} is already running!"
fi

###
CMD="$(/usr/libexec/java_home -v 1.8)/bin/java -jar ${UNIFI_LAUNCHER} ui"
_info "${CMD}"
( eval ${CMD} ) || _error "${CMD}"

Solution 2

This solution requires you to modify the UniFi app files.

Link a Java installation to the UniFi.app:

$ sudo ln -s \
  /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/ \
  /Applications/UniFi.app/Contents/PlugIns/adoptopenjdk-8.jdk

The next step is to tell the UniFi.app to use that by editing the /Applications/UniFi.app/Contents/Info.plist.
Add the JVMRuntime after the JVMOptions:

<key>JVMRuntime</key>
<string>adoptopenjdk-8.jdk</string>

After the update you should be able to start the app like any other app.