HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Guessing the JDK home directory

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
directorythehomeguessingjdk

Problem

My project is using a specific version of JDK which is jdk-6 and the default JDK_HOME path will vary from distribution to distribution, so I wrote a script to guess it. Is there any way to do this better?

#!/bin/bash
JAVA_HOME=""
JDK_TEMP=""
shopt -s extglob

JDK_ROOT_DIR=( /usr/java/ /usr/java/jdk/  /usr/j2se/  /usr/j2se/ /usr/j2sdk/ /usr/jdk/ /usr/lib/java/ /usr/lib/j2se/ /usr/lib/j2sdk/ /usr/lib/jdk/ /usr/lib/jvm/java/ /usr/lib/jvm/j2se/ /usr/lib/jvm/j2sdk/ /usr/lib/jvm/jdk/ /usr/local/java/ /usr/local/java/jdk/ /usr/local/jdk/ /opt/java/ /opt/j2se/ /opt/j2sdk/ /opt/j2sdk/ /opt/jdki/ /usr/lib/jvm/ )
for sub_dir in "${JDK_ROOT_DIR[@]}"
do

#                                                 #
# For each subdirectory inside the root directory #
#                                                 #
#                                                 #
    # For openjdk                                 #
    for jdk_dir in $sub_dir/java-*6*-openjdk*!(common) ; do
        if [[ -d $jdk_dir ]]; then
            echo  $jdk_dir
            export JAVA_HOME=$jdk_dir
            exit 0
        fi
    done

    # for IBM Java                                #
    for jdk_dir in $sub_dir/java-1_6_0-ibm-!(common) ; do
        if [[ -d $jdk_dir ]]; then
            echo $jdk_dir
            export JAVA_HOME=$jdk_dir;
            exit 0
        fi
    done

    # for raspbian java                           #
    for jdk_dir in $sub_dir/jdk-8-oracle-arm32-!(common) ; do
        if [[ -d $jdk_dir ]] ; then
            echo  $jdk_dir
            export JAVA_HOME=$jdk_dir
            exit 0
        fi 
    done
done

echo "JDK directory not found."

Solution

Variables

The line containing the JDK_ROOT_DIR=( … ) definition is so long that it's unreadable and unmaintainable. In fact, you listed /usr/j2se/ twice. It would help to put one entry on each line.

The switch in naming in for sub_dir in "${JDK_ROOT_DIR[@]}" is confusing. Each "root dir" is suddenly being called a "sub dir"?

Your export JAVA_HOME=$jdk_dir statements are pointless, since you immediately exit after setting the variable. For that matter, the initial JAVA_HOME="" and JDK_TEMP="" assignments are also useless.

I know that you don't expect any whitespace or special characters in these directory names, but I would still make it a habit to double-quote variables according to best practice.

Globbing

Your three cases (for OpenJDK, IBM, and Raspbian) are nearly identical and could be handled by a nested loop.

You should also shopt -s nullglob to avoid unnecessarily doing the -d test on failed glob expansions.

Suggested solution

In addition, I think that failure to find the JDK directory should result in a non-zero exit code, and the error message should probably be printed to standard error rather than to standard output.

#!/bin/bash

shopt -s extglob nullglob

JDK_ROOT_DIRS=(
    /usr/java
    /usr/java/jdk
    /usr/j2se
    /usr/j2sdk
    /usr/jdk
    /usr/lib/java
    /usr/lib/j2se
    /usr/lib/j2sdk
    /usr/lib/jdk
    /usr/lib/jvm/java
    /usr/lib/jvm/j2se
    /usr/lib/jvm/j2sdk
    /usr/lib/jvm/jdk
    /usr/local/java
    /usr/local/java/jdk
    /usr/local/jdk
    /opt/java
    /opt/j2se
    /opt/j2sdk
    /opt/jdki
    /usr/lib/jvm
)
SUBDIR_GLOBS=(
    'java-*6*-openjdk*!(common)'            # OpenJDK
    'java-1_6_0-ibm-!(common)'              # IBM Java
    'jdk-8-oracle-arm32-!(common)'          # Raspbian Java
)

for root_dir in "${JDK_ROOT_DIRS[@]}" ; do
    for subdir_glob in "${SUBDIR_GLOBS[@]}" ; do
        for jdk_dir in "$root_dir"/$subdir_glob ; do
            if [ -d "$jdk_dir" ]; then
                echo "$jdk_dir"
                exit 0
            fi
        done
    done
done

echo "JDK directory not found." >&2
exit 1

Code Snippets

#!/bin/bash

shopt -s extglob nullglob

JDK_ROOT_DIRS=(
    /usr/java
    /usr/java/jdk
    /usr/j2se
    /usr/j2sdk
    /usr/jdk
    /usr/lib/java
    /usr/lib/j2se
    /usr/lib/j2sdk
    /usr/lib/jdk
    /usr/lib/jvm/java
    /usr/lib/jvm/j2se
    /usr/lib/jvm/j2sdk
    /usr/lib/jvm/jdk
    /usr/local/java
    /usr/local/java/jdk
    /usr/local/jdk
    /opt/java
    /opt/j2se
    /opt/j2sdk
    /opt/jdki
    /usr/lib/jvm
)
SUBDIR_GLOBS=(
    'java-*6*-openjdk*!(common)'            # OpenJDK
    'java-1_6_0-ibm-!(common)'              # IBM Java
    'jdk-8-oracle-arm32-!(common)'          # Raspbian Java
)

for root_dir in "${JDK_ROOT_DIRS[@]}" ; do
    for subdir_glob in "${SUBDIR_GLOBS[@]}" ; do
        for jdk_dir in "$root_dir"/$subdir_glob ; do
            if [ -d "$jdk_dir" ]; then
                echo "$jdk_dir"
                exit 0
            fi
        done
    done
done

echo "JDK directory not found." >&2
exit 1

Context

StackExchange Code Review Q#147666, answer score: 12

Revisions (0)

No revisions yet.