Skip to main content

Java Detection Utility

Overview

The detect-java-home.sh script provides cross-platform Java detection and JAVA_HOME configuration for consistent builds across different development environments.

Script Location: cli/sdlc/utils/detect-java-home.sh

Purpose

This utility was extracted from deployment scripts to provide reusable Java detection logic across the project. It handles:

  • Dev Container Detection - Automatically uses Temurin 23 JDK in dev containers
  • macOS Support - Uses /usr/libexec/java_home for proper Java detection
  • Linux Support - Derives JAVA_HOME from java command path
  • Cross-Platform Consistency - Ensures same Java version across environments
  • Fallback Handling - Gracefully handles missing Java installations

Use Cases

1. Source in Build Scripts

Use as a library to ensure JAVA_HOME is set before Maven builds:

#!/bin/bash
# Source the utility
source cli/sdlc/utils/detect-java-home.sh

# Detect and set JAVA_HOME
if detect_and_set_java_home; then
echo "Building with Java: $JAVA_HOME"
mvn clean package
else
echo "Failed to detect Java"
exit 1
fi

2. Execute Commands with Correct Java

Run commands with automatically detected Java:

# Execute Maven with correct JAVA_HOME
./cli/sdlc/utils/detect-java-home.sh mvn clean package

# Execute any Java-dependent command
./cli/sdlc/utils/detect-java-home.sh java -version

3. Get Java Home Path

Get the Java home path without setting environment variables:

#!/bin/bash
source cli/sdlc/utils/detect-java-home.sh

JAVA_PATH=$(get_java_home)
echo "Java is installed at: $JAVA_PATH"

Functions

detect_and_set_java_home()

Detects Java installation and exports JAVA_HOME environment variable.

Returns:

  • 0 - Success (Java detected and JAVA_HOME set)
  • 1 - Failure (Java not found)

Detection Order:

  1. Dev container: /usr/lib/jvm/temurin-23-jdk-arm64
  2. macOS: /usr/libexec/java_home utility
  3. Linux: Derive from which java command
  4. Existing: Use already-set JAVA_HOME

Example:

source cli/sdlc/utils/detect-java-home.sh

if detect_and_set_java_home; then
echo "JAVA_HOME is set to: $JAVA_HOME"
mvn --version
else
echo "Java detection failed"
exit 1
fi

get_java_home()

Returns the Java home path without modifying environment variables.

Returns: Path to Java home directory (stdout)

Example:

source cli/sdlc/utils/detect-java-home.sh

JAVA_PATH=$(get_java_home)
if [[ -n "$JAVA_PATH" ]]; then
echo "Java found at: $JAVA_PATH"
echo "Java version: $($JAVA_PATH/bin/java -version 2>&1 | head -1)"
fi

Environment Detection

When running in the project's dev container:

$ source cli/sdlc/utils/detect-java-home.sh
$ detect_and_set_java_home
🔧 Detected dev container Java: /usr/lib/jvm/temurin-23-jdk-arm64

$ echo $JAVA_HOME
/usr/lib/jvm/temurin-23-jdk-arm64

Why: Ensures consistent Java 23 (Temurin) across all developers using the dev container.

macOS

On macOS with Java installed via Homebrew or Oracle:

$ source cli/sdlc/utils/detect-java-home.sh
$ detect_and_set_java_home
🔧 Detected macOS Java (via java_home): /Library/Java/JavaVirtualMachines/temurin-23.jdk/Contents/Home

$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/temurin-23.jdk/Contents/Home

Installation:

# Install Java on macOS
brew install openjdk@23

# Or install Temurin (Eclipse Adoptium)
brew install --cask temurin@23

Linux

On Linux systems with Java installed:

$ source cli/sdlc/utils/detect-java-home.sh
$ detect_and_set_java_home
🔧 Derived JAVA_HOME from java command: /usr/lib/jvm/java-23-openjdk-amd64

$ echo $JAVA_HOME
/usr/lib/jvm/java-23-openjdk-amd64

Installation:

# Ubuntu/Debian
sudo apt update
sudo apt install openjdk-23-jdk

# CentOS/RHEL
sudo yum install java-23-openjdk-devel

# Or install Temurin
wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | sudo apt-key add -
echo "deb https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | sudo tee /etc/apt/sources.list.d/adoptium.list
sudo apt update
sudo apt install temurin-23-jdk

Integration Examples

Maven Build Script

#!/bin/bash
# build.sh - Maven build with automatic Java detection

set -e

# Source Java detection utility
source "$(dirname "$0")/cli/sdlc/utils/detect-java-home.sh"

# Ensure Java is available
if ! detect_and_set_java_home; then
echo "❌ Failed to detect Java. Please install Java 23 or set JAVA_HOME"
exit 1
fi

# Display Java version
echo "Using Java: $JAVA_HOME"
java -version

# Build project
mvn clean package -DskipTests

Deployment Script

#!/bin/bash
# deploy.sh - Deploy with correct Java version

set -e

# Detect Java
source cli/sdlc/utils/detect-java-home.sh
detect_and_set_java_home || exit 1

# Build Docker image with correct Java
echo "Building with JAVA_HOME: $JAVA_HOME"
mvn clean package -DskipTests

# Deploy to Cloud Run
gcloud run deploy my-service \
--source . \
--region us-central1

CI/CD Pipeline

# .github/workflows/build.yml
name: Build

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '23'

- name: Verify Java Detection
run: |
source cli/sdlc/utils/detect-java-home.sh
detect_and_set_java_home
echo "JAVA_HOME: $JAVA_HOME"
java -version

- name: Build with Maven
run: |
source cli/sdlc/utils/detect-java-home.sh
detect_and_set_java_home
mvn clean package -DskipTests

Error Handling

Java Not Found

If Java is not installed:

$ source cli/sdlc/utils/detect-java-home.sh
$ detect_and_set_java_home
❌ Error: Java not found. Please install Java or set JAVA_HOME
Ubuntu/Debian: sudo apt install openjdk-23-jdk
CentOS/RHEL: sudo yum install java-23-openjdk-devel
macOS: brew install openjdk

Solution: Install Java 23 using the provided commands.

Wrong Java Version

If you have a different Java version installed:

# Check current version
java -version

# Install Java 23 (recommended)
# macOS
brew install openjdk@23

# Ubuntu/Debian
sudo apt install openjdk-23-jdk

# Or set JAVA_HOME manually
export JAVA_HOME=/path/to/java-23

Best Practices

1. Source at Script Start

Always source the utility at the beginning of scripts that need Java:

#!/bin/bash
set -e

# Source Java detection utility
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/cli/sdlc/utils/detect-java-home.sh"

# Detect Java
detect_and_set_java_home || exit 1

# Rest of script...

2. Check Return Code

Always check if Java detection succeeded:

if detect_and_set_java_home; then
# Java available, proceed
mvn clean package
else
# Java not found, handle error
echo "Cannot build without Java"
exit 1
fi

3. Use in Dev Container

The dev container is pre-configured with Java 23:

# In dev container, this always works
source cli/sdlc/utils/detect-java-home.sh
detect_and_set_java_home
# Always detects: /usr/lib/jvm/temurin-23-jdk-arm64

4. Document Java Requirements

In your script's help text, document the Java requirement:

show_help() {
cat << EOF
My Build Script

PREREQUISITES:
- Java 23 (automatically detected via detect-java-home.sh)
- Maven 3.8+

USAGE:
$0 [options]
EOF
}

Troubleshooting

Multiple Java Versions

If you have multiple Java versions installed:

# List all Java installations (macOS)
/usr/libexec/java_home -V

# Use specific version
export JAVA_HOME=$(/usr/libexec/java_home -v 23)

# Or manually set
export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-23.jdk/Contents/Home

Dev Container Not Detected

If the dev container Java is not detected:

# Check if path exists
ls -la /usr/lib/jvm/temurin-23-jdk-arm64

# If missing, rebuild dev container
# In VS Code: Cmd+Shift+P -> "Dev Containers: Rebuild Container"

Permission Issues

If Java is installed but not executable:

# Check Java executable permissions
ls -la $(which java)

# Fix permissions if needed (Linux)
sudo chmod +x /usr/bin/java

See Also