Search code examples
javamacosjava-8zshrc

Unable to create Z shell alias to "activate" Java 8 (OpenJDK) on macOS


Summary

I have followed the advice given in this answer to create aliases which allow me to quickly switch between JVM versions on macOS. And I have cross-checked with this article, which suggests a similar solution. This works well for Java 15, but not for Java 8. See details below.

Details

Details of macOS version:

$ sw_vers
ProductName:    macOS
ProductVersion: 12.1
BuildVersion:   21C52

Details of installed Java versions:

$ java --version
java version "15.0.1" 2020-10-20
Java(TM) SE Runtime Environment (build 15.0.1+9-18)
Java HotSpot(TM) 64-Bit Server VM (build 15.0.1+9-18, mixed mode, sharing)

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
    15.0.1 (x86_64) "Oracle Corporation" - "Java SE 15.0.1" /Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home
    1.8.301.09 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
    1.8.0_292 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 8" /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home

And this is from my .zshrc:

# Aliases to quickly change active JVM version

export JAVA_8_HOME=$(/usr/libexec/java_home -v 1.8)
export JAVA_15_HOME=$(/usr/libexec/java_home -v 15)

alias java8="export JAVA_HOME=$JAVA_8_HOME"
alias java15="export JAVA_HOME=$JAVA_15_HOME"

# Set default to Java 15
java15

When I source the .zshrc file, there are no errors.

However, when I run the alias java8, I get the following error:

$ java8
export: not valid in this context: Plug-Ins/JavaAppletPlugin.plugin/Contents/Home

And the active Java version has not changed, i.e., it is still 15.0.1 (my default).

At first, I suspected the version number in my alias was wrong. I have tried changing the name in my .zshrc to the fully qualified name (1.8.0_292):

export JAVA_8_HOME=$(/usr/libexec/java_home -v 1.8.0_292)
alias java8="export JAVA_HOME=$JAVA_8_HOME"

When I run the alias java8 again, after sourcing the updated .zshrc, I no longer get an error. But now my Java environment is in a broken state:

$ java --version
Unrecognized option: --version
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

$JAVA_HOME updates, though, so at least the alias works now:

$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home

Fortunately, I can use my other alias, java15, to get my environment back in a working state:

$ java15
$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home
$ java --version
java 15.0.1 2020-10-20
Java(TM) SE Runtime Environment (build 15.0.1+9-18)
Java HotSpot(TM) 64-Bit Server VM (build 15.0.1+9-18, mixed mode, sharing)

This indicates that the aliases are indeed working, at least java15. But, for some reason, java8 "refuses" to "activate," no matter what version number I put in my alias.

Note that I have installed the OpenJDK version for Java 8, because Oracle's versions are no longer available on their website, nor via Homebrew.

This is exactly how I installed Java 8 on my system, just in case it's relevant:

$ brew tap adoptopenjdk/openjdk
$ brew install adoptopenjdk8

Lastly, I am able to use Java 8 by "manually" specifying it for specific commands, e.g., when using Clojure/Leiningen. For example, this works fine:

$ JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home lein repl

This suggests that the Java 8 installation is indeed working correctly, and that the issue just has to do with my environment and .zshrc somehow.

Update

I discovered jEnv and tried to use that instead of aliases.

Unfortunately, that results in the same problem:

$ brew install openjdk@8

$ jenv add /usr/local/opt/openjdk@8/libexec/openjdk.jdk/Contents/Home
openjdk64-1.8.0.312 added
1.8.0.312 added
1.8 added

$ jenv local 1.8

$ jenv versions
  system
* 1.8 (set by /Users/my-username/my-project-dir/.java-version)
  1.8.0.312
  15
  15.0
  15.0.1
  17
  17.0
  17.0.1
  openjdk64-1.8.0.312
  openjdk64-17.0.1
  oracle64-15.0.1
    
$ java --version
Unrecognized option: --version
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

Solution

  • Oh, my goodness… The answer was in front of my nose all along:

    "Unrecognized option: --version"

    With Java 8, the command --version is invalid. Instead, I had to use -version. Newer versions of Java support both commands (with one or two -), which threw me off.

    $ jenv global 17
    
    $ java --version
    openjdk 17.0.1 2021-10-19
    OpenJDK Runtime Environment Homebrew (build 17.0.1+1)
    OpenJDK 64-Bit Server VM Homebrew (build 17.0.1+1, mixed mode, sharing)
    
    $ java -version
    openjdk version "17.0.1" 2021-10-19
    OpenJDK Runtime Environment Homebrew (build 17.0.1+1)
    OpenJDK 64-Bit Server VM Homebrew (build 17.0.1+1, mixed mode, sharing)
    
    $ jenv global 1.8
    
    $ java --version
    Unrecognized option: --version
    Error: Could not create the Java Virtual Machine.
    Error: A fatal exception has occurred. Program will exit.
    
    $ java -version
    openjdk version "1.8.0_312"
    OpenJDK Runtime Environment (build 1.8.0_312-bre_2022_01_01_23_04-b00)
    OpenJDK 64-Bit Server VM (build 25.312-b00, mixed mode)
    

    That's the dumbest mistake I've made in a while.