8
\$\begingroup\$

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." 
\$\endgroup\$
  • 2
    \$\begingroup\$ urk ... jdk-6? What stops you from migrating to 7, or even better 8? I know for a fact that most webapps won't work properly with jdk-6 anymore because the ciphersuites are too weak by modern standards ... \$\endgroup\$ – Vogel612 Nov 21 '16 at 8:24
  • \$\begingroup\$ @Vogel612 what we are doing is a SDK for a driver, so I don't have that as an option. We have customers who are using JDK-6. But I can use the JDK 7 for compiling which is compatible with JDK 6, but again it is adding more complexities when it comes to building with ant. \$\endgroup\$ – sandun dhammika Nov 21 '16 at 9:03
  • \$\begingroup\$ If you really want to control the JDK you are using the best approach is just include one with your application. \$\endgroup\$ – JimmyJames Nov 21 '16 at 19:15
  • \$\begingroup\$ you mean keep the JDK on the source repository ? We can't ship it to customers, because they could use JDK7 or 8 and i can't force that. What I need is that backward compatibility, when I compile with JDK 6 , it should work JDK 7 too \$\endgroup\$ – sandun dhammika Nov 22 '16 at 4:30
  • \$\begingroup\$ What's wrong with whereis javac? \$\endgroup\$ – Maybe_Factor Nov 23 '16 at 1:05
12
\$\begingroup\$

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
\$\endgroup\$
  • 1
    \$\begingroup\$ If JAVA_HOME is already set, then you should use that. \$\endgroup\$ – Stop Harming Monica Nov 21 '16 at 13:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.