Saturday, March 31, 2018

Workaround for jenv on Cygwin

I'd like to use jenv on my Cygwin setup at home. Oracle has moved to a 6-month release pace, and so I find myself dealing with multiple Java major verions. However, my tool of choice, jenv, does not play well with Cygwin.

(Note: There are two jenvs out there. I am talking about jenv.be, not jenv.io. Apologies that neither does HTTPS well.)

As a workaround, I wrote a straight-forward shell function to provide the minimum I need: switch between versions in the current shell:

# Until jenv.be supports Cygwin
function set-java {
    local -a java_v
    local jdk v OPTIND
    for jdk in /cygdrive/c/Program\ Files/Java/jdk*
    do
        jdk="${jdk/\/cygdrive\/c\/Program\ Files\/Java\/jdk/}"
        v=${jdk#-}
        v=${v#1.}
        v=${v%%.*}
        java_v[$v]=$jdk
    done

    local verbose=false
    while getopts :hv opt
    do
        case $opt in
        h ) cat <<EOH
            Usage: $FUNCNAME [-hv] VERSION

            Options:
            -h Print help and exit
            -v Verbose output

            Arguments:
            VERSION One of ${!java_v[@]}
            EOH
            return 0 ;;
            v ) verbose=true ;;
            * ) echo "Usage: $FUNCNAME [-hv] VERSION" >&2 ; return 2 ;;
        esac
    done
    shift $((OPTIND - 1))

    case $# in
    1 ) ;;
    * ) echo "Usage: $FUNCNAME [-hv] VERSION" >&2 ; return 2 ;;
    esac

    if ! [[ ${java_v[$1]+foo} ]]
    then
        echo "$FUNCNAME: No such Java version: $1.  Try $FUNCNAME -h" >&2
        return 2
    fi

    export JAVA_HOME='C:\Program Files\Java\jdk'${java_v[$1]}
    for v in ${!java_v[@]}
    do
        case $v in
        $1 ) ;;
        * ) export PATH="${PATH//${java_v[$v]}/${java_v[$1]}}" ;;
        esac
    done

    if $verbose
    then
        echo "$FUNCNAME: Updated JAVA_HOME and PATH for JDK to $v at $JAVA_HOME"
    fi
}

Try the -h flag (help).