【Java】JAVA_HOMEとは -使われ方とその必要性-

Java

JAVA_HOMEとは

javaコマンドやそれに関連するコマンドの設定を行っていると、JAVA_HOME というものに出会うことがあります。JAVA_HOME とは、一言でいうと、Java(JDKまたはJRE)をインストールしたディレクトリの絶対パスを設定した環境変数のこと、です。

環境変数についてはこちらに詳細を記載しています。

このページでは、Java や Java のビルドツールである Ant・Maven 等の設定と実行例を見ながら、JAVA_HOME という環境変数がどのように利用されるのかを確認していきます。

JAVA_HOME
Java(JDKまたはJRE)のインストールディレクトリの絶対パスを設定した環境変数

JAVA_HOMEの必要性

例)Java

先述の通り、javaコマンド設定の際、JAVA_HOME という環境変数が出てきて、環境変数PATHと一緒に、この設定を併せて行うことがあります。しかし単にJavaだけを使用して開発を進めていくうちは、特に JAVA_HOME を使う場面もなく、結局よく分からないままになっているということもあるかもしれません。

それも当然で、javaコマンドの設定にあたり、JAVA_HOME の設定は必須の手順ではありません。例えば、以下の手順では JAVA_HOME の設定を行っていませんが、環境変数PATH に直接 Java( JDKまたはJRE )の bin ディレクトリを追加することで、PATHを通しています。このように、javaコマンドの設定を行うだけであれば、JAVA_HOME を介して PATH の追加を行う必要はありません。

# javaコマンドが認識されておらず実行できない
$ java --version
'java' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# 環境変数 PATH に Java(JDKまたはJRE)の bin ディレクトリを追加
$ set PATH=%PATH%;C:\Users\xxx\workspace\jdk-23_windows-x64_bin\jdk-23.0.1\bin

# javaコマンドが認識されており実行できる
$ java --version
java 23.0.1 2024-10-15
Java(TM) SE Runtime Environment (build 23.0.1+11-39)
Java HotSpot(TM) 64-Bit Server VM (build 23.0.1+11-39, mixed mode, sharing)
上記手順の詳細はこちらです。この手順では JAVA_HOME の設定を省略しています。

しかし、通常は以下のように、環境変数 PATH の前にまず JAVA_HOME の設定を行う手順が一般的です。

Once this is done you need to create an environment variable called JAVA_HOME that points to the directory where you unzipped the JDK.
これが完了したら、JDK を解凍したディレクトリを指す JAVA_HOME という環境変数を作成する必要があります。

> set JAVA_HOME=D:\jdk\jdk-22

You then need to update your PATH environment variable to add the bin directory of your JDK directory to it.
次に、PATH 環境変数を更新して、JDK ディレクトリの bin ディレクトリを追加する必要があります。

> set PATH=%JAVA_HOME%\bin;%PATH%

Getting Started with Java > Setting up a JDK for Windows/x64

ではなぜ、javaコマンドを直接 PATH に設定せず、わざわざ必須ではない環境変数 JAVA_HOME を定義するのかというと、今後必要となる可能性が高いからです。今は必要でなくとも、いずれ設定することになるのであれば、事前に設定しておこうというわけです。

必要になるタイミングというのは、内部でJavaを利用している別のアプリケーション(プログラム)を利用する時です。例えばJavaのビルドツールの一つである Ant は、内部でJavaを利用しているため、Antがjavaコマンドを実行できるように設定されていないと、antコマンドの実行にも失敗してしまいます。このように他のプログラムからjavaコマンドが呼び出される場合、環境変数 JAVA_HOME が使用されます。

従って JAVA_HOME とは Java自体が利用するものではなく、むしろ他のプログラムがJavaを利用する際に参照するためのものです。

JAVA_HOME
他のプログラムがJavaを利用する際に参照するための環境変数

これがjavaコマンド設定の際に JAVA_HOME の設定が必須ではない理由です。そして JAVA_HOME を先に設定することが多い理由でもあります。Javaの開発に伴って使用するツールの多く(Ant・Maven・Tomcat 等)は内部でJavaを利用しており、javaコマンドの設定をするということは、これからJavaを利用した開発を始めるということでもあり、先に設定しておくほうが合理的だからです。

基本的に JAVA_HOME は Java が使用する環境変数ではありませんが、PATH に直接設定せず、JAVA_HOME を介することで、例えばバージョンを変更したい時などにそれが容易になるという利点もあります。

例えば、以下のようにJavaの bin ディレクトリが直接 PATH に設定されていたとします。この場合、Javaのバージョンを変更する時には、値がいくつも ; で連結された PATH の変数値のうち、Javaの部分だけを適切に変更する必要があります。

PATH=C:\Users\xxx\AAA\aaa;C:\Users\xxx\BBB\bbb;C:\Users\xxx\java\jdk-23.0.1\bin;C:\Users\xxx\CCC\ccc;
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                               └> この部分(複数の値に紛れた一部のパス)を置き換える必要がある。

これが、JAVA_HOME の参照を利用して PATHbin ディレクトリが設定されていた場合、JAVA_HOME に設定された値を変更するだけで、PATH の値も変えることができるようになります。

PATH=C:\Users\xxx\AAA\aaa;C:\Users\xxx\BBB\bbb;%JAVA_HOME%\bin;C:\Users\xxx\CCC\ccc;
                                               ^^^^^^^^^^^
JAVA_HOME=C:\Users\xxx\java\jdk-23.0.1
^^^^^^^^^
└> JAVA_HOMEの値を変更するだけで良くなる。

※ただしこの例のように JAVA_HOME の変更を PATH にも反映させるためには、どちらも永続的な環境変数の設定が必要である点は注意が必要です。

別の環境変数への参照と永続設定の関係についてはこちらで整理しています。

またここまでの例から分かる通り、Javaのみで(本来は不要の)JAVA_HOME を利用(PATH に直接設定するのを避けるためだけに利用)する場合、変数名は JAVA_HOME でなくとも問題はありません。例えば以下のようにsetxコマンドの説明には「JAVADIR」という環境変数が使用されています。(※ 後述 の通り、他のプログラムから利用される際は、慣例的に JAVA_HOME という名前が使用されるため、この限りではありません。)

既存の変数に対してこのコマンドを実行すると、変数の参照が削除されて、展開された値が使用されます。

たとえば、変数 %PATH% に %JAVADIR% への参照が含まれている場合、setx を使用して %PATH% を操作すると、%JAVADIR% が展開され、その値がターゲット変数 %PATH% に直接割り当てられます。 これは、%JAVADIR% に対するその後の更新が、%PATH% 変数に反映されないことを意味します。

setx > 解説

では、他のプログラムがJavaを利用するとは具体的にどういうことか、Ant( antコマンド )の設定を例に確認してみます。

例)Ant

ここから、Ant( antコマンド )設定を例に、JAVA_HOME の使われ方を確認していきます。Antがjavaコマンドを呼び出すということの具体的なイメージが湧きやすくなります。

まずは .zip をダウンロードして展開し、bin ディレクトリにPATHを通します。

PATHの通し方についてはこちらを確認してください。

Antは以下ページよりダウンロードすることが可能です。
Apache Ant > Download > Binary Distributions

以降の手順では、これを解凍した場所をAntのインストールディレクトリとし、その下の bin ディレクトリにPATHを通していきます。

環境変数 PATH に追加したAntの bin ディレクトリには、Windows用の実行ファイルとして ant.batant.cmd の二種類が含まれていますが、拡張子を指定せず単に ant と打った場合は、ant.bat がコマンドとして実行されます。

これは、拡張子を省略した際に使用される環境変数 PATHEXT のデフォルト値が、.BAT.CMD の順で設定されており、優先順位の高い拡張子を持つ ant.bat が選択されるためです。

環境変数 PATHEXT の詳細はこちらです。

しかしPATHを通しても、次のように新たに別のエラーが出力されるようになってしまいます。

  1. $ ant -version → ‘ant’ は・・・認識されていません。
  2. PATHを通す。
  3. $ ant -version → ‘”java.exe”‘ は・・・認識されていません。
# antコマンドが認識されておらず実行できない
$ ant -version
'ant' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# Ant の bin ディレクトリを PATH に追加
$ set PATH=%PATH%;C:\Users\xxx\apache-ant-1.10.15\bin

# antコマンド自体は認識されているものの
# 内部で利用しているjavaコマンドが認識されていないためエラー
$ ant -version
'"java.exe"' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

これは、antコマンドが内部でjavaコマンドを使用しており、前提としてjavaコマンドが実行できるように設定された環境でなければ、antコマンドを実行することができないためです。

1. Make sure you have a Java environment installed.
1. Java環境がインストールされていることを確認してください。

Installing Apache Ant > Getting Apache Ant > The Short Story

従って次のように、併せてJavaにPATHを通し、javaコマンドも実行できるようにしておくことで、正常にantコマンドを実行できるようになります。

# antコマンドが認識されておらず実行できない
$ ant -version
'ant' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# Ant の bin ディレクトリを PATH に追加
$ set PATH=%PATH%;C:\Users\xxx\apache-ant-1.10.15\bin

# antコマンド自体は認識されているものの
# 内部で利用しているjavaコマンドが認識されていないためエラー
$ ant -version
'"java.exe"' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# PATH が通っていないためjavaコマンドを実行できないことを確認
$ java -version
'java' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# Java の bin ディレクトリを PATH に追加
$ set PATH=%PATH%;C:\Users\xxx\jdk-23.0.1\bin

# javaコマンドを実行できるようになったことを確認
$ java -version
java version "23.0.1" 2024-10-15
Java(TM) SE Runtime Environment (build 23.0.1+11-39)
Java HotSpot(TM) 64-Bit Server VM (build 23.0.1+11-39, mixed mode, sharing)

# javaコマンドを利用できるようになったことにより
# antコマンドも正常に実行できる
$ ant -version
Apache Ant(TM) version 1.10.15 compiled on August 25 2024

これが、他のプログラムが内部でJavaを利用している、ということです。このように、利用したいコマンドがJavaに依存している場合、そのコマンドの PATH 設定とは別に、Javaの設定も別途必要になります。そしてそのプログラムは、設定されたJavaの場所を正しく認識しておく必要があります。

しかしこれは、必ずしもPATHを通してjavaコマンドを利用できるようにしておくことと同義ではありません。あくまで環境変数PATHは、システム上でコマンド実行する際、そのプログラムの絶対パスを指定しなくても済むようにするためのものであるからです( 環境変数PATH )。

そのため他のプログラムから呼び出す場合、Javaの場所(=java.exe までの絶対パス)さえ分かれば、PATHを通すこと自体は必須ではないと言えます。この時、antコマンドが java.exe までのパスを解決するため、PATH とは独立したAnt用の環境変数を設定できると便利です。ここで使用されるのが JAVA_HOME です。

下記の通り、Antではjavaコマンドのパス( C:\Users\...\jdk\bin\java.exe )を解決するために JAVA_HOME という名前の環境変数を利用することができます。そして環境変数 JAVA_HOME が設定されている場合、PATH に設定されているものよりも優先して、JAVA_HOME に設定されている方の java.exe が使用されます。

JAVA_HOME is used by the launcher for finding the JDK/JRE to use. (JDK is recommended as some tasks require the Java tools.) If not set, the launcher tries to find one via the %PATH% environment variable.
JAVA_HOME は、使用する JDK/JRE を見つけるためにランチャーによって使用されます。(一部のタスクではJavaツールが必要なので、JDKが推奨されます。)設定されていない場合、ランチャーは %PATH% 環境変数を介して検索を試みます。

Installing Apache Ant > Installing Ant > Check Installation

このようにAntでは、Javaを認識するための環境変数に JAVA_HOME という変数名が使用されます。そして後述の通り、MavenやTomcatでも同じように JAVA_HOME という変数名が使用されます。そのため、一度 JAVA_HOME という環境変数を定義してしまえば、以降さまざまなJavaを内部利用するプログラムから参照させることができます。

しかし留意すべき点は、この JAVA_HOME という変数名に必然性はなく、Javaを認識させるための環境変数の名称として恣意的に決定されたものであるということです。従って、あくまで多くのプログラムでたまたま JAVA_HOME という変数名がよく使われているというだけの単なる慣習に過ぎません。

JAVA_HOME
慣例的に「 JAVA_HOME 」という変数名が使用される

あるアプリケーションをインストールして解凍した、そのプログラムのルートとなるディレクトリを設定する環境変数には、「○○_HOME」という変数名が使用されることが多くあります。この変数値にインストールディレクトリを設定しておくことで、そのアプリケーションのディレクトリを変更したくなった際、「○○_HOME」の設定値を変更するだけで、内部で参照している各パスに対する変更の影響を抑えることができます。

そのため、Javaのホームディレクトリを設定する環境変数の名称が「JAVA_HOME」となるのは、ある意味では必然かもしれません。

以下は「○○_HOME」という名称の環境変数の例です。

Antでは ANT_HOME という環境変数が使用されます。JAVA_HOME 同様、直下の bin ディレクトリに ant.bat が含まれるため、%ANT_HOME%\binPATH に追加するといった設定が可能となります。

4. Set environmental variables: JAVA_HOME to your Java environment, ANT_HOME to the directory you uncompressed Ant to, and add ${ANT_HOME}/bin (Unix) or %ANT_HOME%\bin (Windows) to your PATH.
4. 環境変数を設定します: JAVA_HOME をJava環境に、ANT_HOME をAntを解凍したディレクトリに設定し、PATH${ANT_HOME}/bin(Unix)または %ANT_HOME%\bin(Windows)を追加します。

Installing Apache Ant > Getting Apache Ant > The Short Story

このように「○○_HOME」を使用する場合、bin ディレクトリ下の実行ファイルの絶対パス指定が容易になるため、PATH に追加せずそのまま変数値を使用してコマンド実行に利用することもできます。例えば MAVEN_HOME を利用する場合、後述 の通り、%MAVEN_HOME%\bin\mvn のように実行することが可能です。

Tomcatでは、インストールディレクトリを指す環境変数に CATALINA_HOME を使用しますが、これは JAVA_HOME 等と異なり、Tomcat自身が内部で利用し、かつ設定が必須のホームディレクトリ参照用環境変数となります。( 後述

その他、Oracle Database では、インストールディレクトリのパスを ORACLE_HOME という環境変数に指定して初期設定を行います。

ORACLE_HOME
Oracle製品がインストールされるOracleホーム・ディレクトリを指定します。

データベース管理者リファレンス for Microsoft Windows > ORACLE_HOME

次に示すのは JAVA_HOME を使用した設定例です。PATHjavaコマンドの設定がなくても、antコマンドを実行できている点に注目してください。また、JAVA_HOME は JDKやJRE等のJavaインストールディレクトリを設定する環境変数であるため、PATH と異なり bin ディレクトリは含めません。\bin\java.exe の部分はAntによって補われます。( Mavenのmvn.cmdに関する項 でも詳述 )

# PATH には Ant のみ設定されている
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\xxx\apache-ant-1.10.15\bin;

# PATHが通っていないためjavaコマンドは実行できない
$ java -version
'java' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# JAVA_HOME は未定義
$ echo %JAVA_HOME%
%JAVA_HOME%

# 環境変数 JAVA_HOME を作成
# bin ディレクトリは含めず JDK までのパスを設定する
$ set JAVA_HOME=C:\Users\...\jdk-23.0.1

# JAVA_HOME が正しく定義されたことを確認
$ echo %JAVA_HOME%
C:\Users\...\jdk-23.0.1

# javaコマンドにPATHを通していなくても JAVA_HOME が定義されているため
# Ant はこれをもとに %JAVA_HOME%\bin\java.exe を見つけることができ
# 内部でjavaコマンドを利用しているantコマンドを実行できる
$ ant -version
Apache Ant(TM) version 1.10.15 compiled on August 25 2024

では、わざわざ PATH と分けて設定を行うメリットはなんでしょうか。一つは、システムで使用しているjavaコマンドとAntが使用するものとを分けることにより、柔軟な変更が可能となることです。

例えばコマンドによってはJavaのバージョンに制約があり、普段利用しているJavaのバージョンと異なる場合、これが問題になることがあります。例として Ant 1.10.* では、Java に 8 以降のバージョンが設定されている必要があります。

For the current version of Ant (1.10), you will also need a JDK installed on your system, version 8 or later required.
Ant の現在のバージョン (1.10) の場合、システムに JDK がインストールされている必要があり、バージョン 8 以降が必要です。

Installing Apache Ant > System Requirements

そのため例えば PATH にJava7が設定されていると、次のようにエラーが発生してしまいます。

# PATH には Java1.7 と Ant1.10 が設定されている
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\xxx\jre1.7.0_80\bin;...;C:\Users\xxx\apache-ant-1.10.15\bin;

# javaコマンドでJavaのバージョンを確認
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

# antコマンドでAntのバージョンを確認
# Java8(クラスファイル52.0)未満のためエラーが発生
$ ant -version
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/tools/ant/launch/Launcher : Unsupported major.minor version 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

エラーメッセージに、Unsupported major.minor version 52.0 と出力されていることから、Java8(クラスファイルのバージョンが52.0)以上であることが求められていると分かります。

クラスファイルのバージョンについてはこちらに対応表を記載しています。

そこで、Javaのバージョンを上げ、例えばJava8等にする必要がありますが、これは環境変数PATHの先頭に新たにJavaのパスを追加したり、設定済みのパスを置換したりすることで対応できます( 追加 置換 )。しかしこの場合の問題点は、通常のjavaコマンド使用時のバージョンも変更されてしまうということです。

# PATH には Java1.7 と Ant1.10 が設定されている
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\xxx\jre1.7.0_80\bin;...;C:\Users\xxx\apache-ant-1.10.15\bin;

# javaコマンドでJavaのバージョンを確認
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

# antコマンドでAntのバージョンを確認
# Java8(クラスファイル52.0)未満のためエラーが発生
$ ant -version
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/tools/ant/launch/Launcher : Unsupported major.minor version 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

# PATH に設定された Java のバージョンを変更
$ set PATH=%PATH:jre1.7.0_80=jre1.8.0_431%

# Java のパスが置き換わっていることを確認
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\xxx\jre1.8.0_431\bin;...;C:\Users\xxx\apache-ant-1.10.15\bin;

# antコマンドを実行できAntのバージョンが出力される
$ ant -version
Apache Ant(TM) version 1.10.15 compiled on August 25 2024

# javaコマンドのバージョンも変わってしまう
$ java -version
java version "1.8.0_431"
Java(TM) SE Runtime Environment (build 1.8.0_431-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.431-b10, mixed mode)

このような場合に、JAVA_HOME によって PATH と分けておくことで、Antが利用するJavaだけを変更することが可能となります。以下は JAVA_HOME を定義した場合のコマンド例です。( 新規作成 確認方法

# PATH には Java1.7 と Ant1.10 が設定されている
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\xxx\jre1.7.0_80\bin;...;C:\Users\xxx\apache-ant-1.10.15\bin;

# javaコマンドでJavaのバージョンを確認
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

# antコマンドでAntのバージョンを確認
# Java8(クラスファイル52.0)未満のためエラーが発生
$ ant -version
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/tools/ant/launch/Launcher : Unsupported major.minor version 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

# JAVA_HOME は未定義
$ echo %JAVA_HOME%
%JAVA_HOME%

# 環境変数 JAVA_HOME を作成
# bin ディレクトリは含めず JRE までのパスを設定する
$ set JAVA_HOME=C:\Users\xxx\jre1.8.0_431

# JAVA_HOME が正しく定義されたことを確認
$ echo %JAVA_HOME%
C:\Users\xxx\jre1.8.0_431

# PATH に設定されているのは変わらずJava7
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\xxx\jre1.7.0_80\bin;...;C:\Users\xxx\apache-ant-1.10.15\bin;

# JAVA_HOME が定義されている場合は PATH より優先されるため
# Java8 が使用されて正常にantコマンドを実行できる
$ ant -version
Apache Ant(TM) version 1.10.15 compiled on August 25 2024

# PATH の設定は変更していないため
# javaコマンドはこれまで通りJava7の方を使用できる
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

このように JAVA_HOME とは、あるプログラムが内部でJavaを利用する時に java.exe の場所を認識するため、Java(JDKやJRE)がインストールされたディレクトリのパスを設定しておく環境変数です。

はじめに Javaの項 JAVA_HOME の設定は必須ではないと言いましたが、実際には必須でないどころか、Javaにとっては無くても全く問題のないものです。JAVA_HOME という環境変数は、Javaの内部動作で使用されることは一切なく、あくまでJavaを利用する側のプログラムにとって必要なものであるためです。

JAVA_HOME
Javaが参照するものではない

例)Maven

ここまでAntを例に JAVA_HOME の説明をしてきましたが、ビルドツールとしては Maven の方がなじみ深いかもしれません。MavenもAntと同じように、Javaを参照するために JAVA_HOME という名前の環境変数を利用しており、設定されている場合は PATH よりも JAVA_HOME が優先されます。

Prerequisites
前提条件

You need a Java Development Kit (JDK) installed. Either set the JAVA_HOME environment variable to the path of your JDK installation or have the java executable on your PATH.
Java開発キット(JDK)がインストールされている必要があります。JAVA_HOME 環境変数にJDKをインストールしたパスを設定するか、PATHjava 実行可能ファイルを配置してください。

The current stable version 3.9.9 requires JDK 8+, but any recent version will work just fine.
現在の安定バージョン 3.9.9 には JDK 8 以上が必要ですが、最近のバージョンであれば問題なく動作します。

Apache > Maven > Installation

以下はAntの例で示したのと同じような検証の例です。

まずはmvnコマンドを利用できるようにします。Mavenは以下ページよりダウンロードすることが可能です。
Apache > Maven > Download Apache Maven > Files

これを解凍した場所をMavenのインストールディレクトリとし、その下の bin ディレクトリにPATHを通します。しかしMavenもAntと同じように内部でJavaを利用しているため、PATHJAVA_HOME どちらにもJavaが設定されていない場合、mvnコマンドにPATHを通しただけではエラーが出力されてしまいます。(以降の例では PATH の設定に pathコマンド を使用しています。)

# mvnコマンドが認識されておらず実行できない
$ mvn -v
'mvn' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# Maven の bin ディレクトリを PATH に追加
$ path %PATH%;C:\Users\...\apache-maven-3.9.9\bin

# Maven が PATH に追加されていることを確認
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\...\apache-maven-3.9.9\bin

# mvnコマンド自体は認識されているもののjavaコマンドを実行できずエラー
# PATH にも JAVA_HOME にも Java の設定が行われていない場合
# 環境変数 JAVA_HOME を定義するようエラーメッセージが出力される
$ mvn -v
The JAVA_HOME environment variable is not defined correctly,
this environment variable is needed to run this program.

この対応として、javaコマンドにPATHを通すか、環境変数 JAVA_HOME を定義する必要があります。まずは PATH に直接追加する場合の例です。この場合、JAVA_HOME の定義は不要です。

# PATH にも JAVA_HOME にも Java の設定が行われていない場合
# 環境変数 JAVA_HOME を定義するようエラーメッセージが出力される
$ mvn -v
The JAVA_HOME environment variable is not defined correctly,
this environment variable is needed to run this program.

# Java の bin ディレクトリを PATH に追加
$ path %PATH%;C:\Users\...\jdk-23.0.1\bin

# Java が PATH に追加されていることを確認
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\...\apache-maven-3.9.9\bin;C:\Users\...\jdk-23.0.1\bin

# 環境変数 JAVA_HOME は未定義であることを確認
$ echo %JAVA_HOME%
%JAVA_HOME%

# Java を PATH に追加したことでmvnコマンドを正常に実行できる
$ mvn -v
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: C:\Users\...\apache-maven-3.9.9
Java version: 23.0.1, vendor: Oracle Corporation, runtime: C:\Users\...\jdk-23.0.1
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

続いて、JAVA_HOME を利用する場合のコマンド例です。この場合は逆に、javaコマンドにPATHを通す必要はありません。

# PATH にも JAVA_HOME にも Java の設定が行われていない場合
# 環境変数 JAVA_HOME を定義するようエラーメッセージが出力される
$ mvn -v
The JAVA_HOME environment variable is not defined correctly,
this environment variable is needed to run this program.

# 環境変数 JAVA_HOME を定義
$ set JAVA_HOME=C:\Users\...\jdk-23.0.1

# JAVA_HOME が定義されていることを確認(binディレクトリは含まない)
$ echo %JAVA_HOME%
C:\Users\...\jdk-23.0.1

# PATH には Maven のみ設定されており Java は追加されていない
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\...\apache-maven-3.9.9\bin

# javaコマンドは実行できない状態
#(※PATHを通していないだけのため絶対パス指定 C:\Users\...\jdk-23.0.1\bin\java -version では実行可能な状態)
$ java -version
'java' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# PATH には追加されていないものの Maven からは JAVA_HOME を介してjavaを実行できるため
# 単体でjavaコマンドを実行できない状態であってもmvnコマンドを実行できる
$ mvn -v
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: C:\Users\...\apache-maven-3.9.9
Java version: 23.0.1, vendor: Oracle Corporation, runtime: C:\Users\...\jdk-23.0.1
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

PATHJAVA_HOME の両方を設定した場合は、Ant同様 JAVA_HOME に設定した方のJavaが優先して使用されます。このため、javaコマンドとは異なるバージョンのJavaをMavenに利用させることができます。(ちなみにこの例の場合、JAVA_HOME を削除すると PATH に設定されたJava7が使用されることになりますが、Mave 3.9.9 ではサポートされていないためエラーが発生します。)

# PATH には Maven と Java の両方が設定されている
# PATH に設定された Java のバージョンは 7
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\...\apache-maven-3.9.9\bin;C:\Users\...\jre1.7.0_80\bin

# JAVA_HOME も定義されている
# JAVA_HOME に設定された Java のバージョンは 8
$ echo %JAVA_HOME%
C:\Users\...\jre1.8.0_431

# mvnコマンドを利用できる
#「Java version:」の出力から Maven で使用されているのは JAVA_HOME に設定した Java8 の方であることが分かる
$ mvn -v
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: C:\Users\...\apache-maven-3.9.9
Java version: 1.8.0_431, vendor: Oracle Corporation, runtime: C:\Users\...\jre1.8.0_431
Default locale: ja_JP, platform encoding: MS932
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

# javaコマンドも利用できる
# 直接javaコマンドを実行した場合は PATH に設定した Java7 の方が使用されることが分かる
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

# またこの例の場合 JAVA_HOME を削除し
$ set JAVA_HOME=

# 環境変数 JAVA_HOME が未定義の状態で
$ echo %JAVA_HOME%
%JAVA_HOME%

# mvnコマンドを実行しようとすると PATH に設定された Java7 が使用されることになり
# Maven 3.9.9 では Java8 以上が要求されているためエラーが発生する
$ mvn -v
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/codehaus/plexus/classworlds/launcher/Launcher : Unsupported major.minor version 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

また、JAVA_HOME は通常 bin ディレクトリを含めず、その一つ上のJavaのインストールディレクトリまでの絶対パスを設定します。これは PATH に設定する bin までのパスとは異なるため注意が必要です。

PATH の場合は、対象のコマンドを設定値から走査する際、java.exe が含まれる bin ディレクトリまでのパスが設定されている必要があるためです。一方 JAVA_HOME は、例えばMavenでも、インストールディレクトリが設定されるという慣習に基づき、bin ディレクトリを補って java.exe を呼び出すような使われ方をします。

Maven の bin ディレクトリに配置された mvn.cmd をメモ帳で開き、内容を確認してみると、以下のように %JAVA_HOME%\bin\java.exeJAVACMDjavaコマンド)として設定している処理が見つかります。

@setlocal

set ERROR_CODE=0

@REM ==== START VALIDATION ====
if not "%JAVA_HOME%"=="" goto OkJHome
for %%i in (java.exe) do set "JAVACMD=%%~$PATH:i"
goto checkJCmd

:OkJHome
set "JAVACMD=%JAVA_HOME%\bin\java.exe"

:checkJCmd
if exist "%JAVACMD%" goto chkMHome

echo The JAVA_HOME environment variable is not defined correctly, >&2
echo this environment variable is needed to run this program. >&2
goto error

:chkMHome
set "MAVEN_HOME=%~dp0"
set "MAVEN_HOME=%MAVEN_HOME:~0,-5%"
if not "%MAVEN_HOME%"=="" goto checkMCmd
goto error

:checkMCmd
if exist "%MAVEN_HOME%\bin\mvn.cmd" goto init
goto error
@REM ==== END VALIDATION ====

:init

上記 mvn.cmd 内では JAVA_HOME の他、MAVEN_HOME という環境変数も使用されていますが、このように特定のアプリケーションのルートとなるディレクトリを環境変数に設定しておくことで、PATHを通さず絶対パスを指定したコマンドの実行が容易になります(例えばMavenの場合は %MAVEN_HOME%\bin\mvn )。これにより、インストールディレクトリを変更したい場合など、PATH の設定に触れず、MAVEN_HOME の変数値だけを変更することで対応することが可能です。

# PATH に設定されているのは Java のみ
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\...\jdk-23.0.1\bin

# MavenにはPATHが通っていないためコマンド実行できない
$ mvn -v
'mvn' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

# 絶対パスを指定すれば実行できる(PATHEXT により拡張子は省略可能)
$ C:\Users\...\apache-maven-3.9.9\bin\mvn -v
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: C:\Users\...\apache-maven-3.9.9
Java version: 23.0.1, vendor: Oracle Corporation, runtime: C:\Users\...\jdk-23.0.1
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

# 環境変数 MAVEN_HOME を作成して Maven のインストールディレクトリを設定する
$ set MAVEN_HOME=C:\Users\...\apache-maven-3.9.9

# MAVEN_HOME が定義されていることを確認
$ echo %MAVEN_HOME%
C:\Users\...\apache-maven-3.9.9

# MAVEN_HOME を利用することで PATH 設定なしに絶対パスを指定してコマンド実行が可能
# インストールディレクトリを変更したい場合も PATH の設定を変更することなく
# MAVEN_HOME の値のみを変更すれば他プログラムへの影響を抑えて対応が可能となる
$ %MAVEN_HOME%\bin\mvn -v
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: C:\Users\...\apache-maven-3.9.9
Java version: 23.0.1, vendor: Oracle Corporation, runtime: C:\Users\...\jdk-23.0.1
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

例)Tomcat

続いて Tomcat の例です。AntやMavenではJavaを認識させるため、PATH または JAVA_HOME いずれかを設定すれば良かったのですが、Tomcatの場合は JAVA_HOME の設定が必須となります。

# PATH に Java を設定済み
$ path
PATH=C:\AAA\aaa;C:\BBB\bbb;...;C:\Users\...\jdk-23.0.1\bin

# javaコマンドを実行できる状態
$ java -version
java version "23.0.1" 2024-10-15
Java(TM) SE Runtime Environment (build 23.0.1+11-39)
Java HotSpot(TM) 64-Bit Server VM (build 23.0.1+11-39, mixed mode, sharing)

# JAVA_HOME は未定義
$ echo %JAVA_HOME%
%JAVA_HOME%

# Tomcat のインストールディレクトリへ移動
$ cd C:\Users\...\apache-tomcat-11.0.5

# bin ディレクトリの startup.bat を使って Tomcat を起動
# JAVA_HOME が定義されていないためエラー
$ bin\startup.bat
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program

# JAVA_HOME を定義
$ set JAVA_HOME=C:\Users\...\jdk-23.0.1

# インストールディレクトリが設定されていることを確認
$ echo %JAVA_HOME%
C:\Users\...\jdk-23.0.1

# bin ディレクトリの startup.bat を使って Tomcat を起動
$ bin\startup.bat
Using CATALINA_BASE:   "C:\Users\...\apache-tomcat-11.0.5"
Using CATALINA_HOME:   "C:\Users\...\apache-tomcat-11.0.5"
Using CATALINA_TMPDIR: "C:\Users\...\apache-tomcat-11.0.5\temp"
Using JRE_HOME:        "C:\Users\...\jdk-23.0.1"
Using CLASSPATH:       "C:\Users\...\apache-tomcat-11.0.5\bin\bootstrap.jar;C:\Users\...\apache-tomcat-11.0.5\bin\tomcat-juli.jar"
Using CATALINA_OPTS:   ""

bin\startup.bat が正常に実行されると、別ウィンドウでコマンドプロンプトが開き、Tomcat起動ログが出力されます。この状態で、デフォルトでは http://localhost:8080/ でブラウザからトップページへ接続することができます。

起動後、Tomcatは以下いずれかの方法で停止させることができます。

  • 新しく開かれたコマンドプロンプト(Tomcat起動ログが出力されている別ウィンドウ)で「 Ctrl + C 」を押下する。
  • 元のコマンドプロンプト( bin\startup.bat を実行した所 )で今度は bin\shutdown.bat を実行する。

Java location: The installer will provide a default JRE to use to run the service. The installer uses the registry to determine the base path of a Java 17 or later JRE, including the JRE installed as part of the full JDK. The installer will first look for a JRE and only look for a JDK if a JRE is not found. Finally, if a JRE or JDK has not been found, the installer will try to use the JAVA_HOME environment variable. It is not mandatory to use the default JRE detected by the installer. Any installed Java 17 or later JRE may be used.
Javaの場所: インストーラはサービスを実行するために使用するデフォルトのJREを提供します。インストーラはレジストリを使用して、完全なJDKの一部としてインストールされたJREを含む、Java17以降のJREのベースパスを決定します。インストーラは最初にJREを検索し、JREが見つからない場合にのみJDKを検索します。最後に、JREまたはJDKが見つからない場合、インストーラは JAVA_HOME 環境変数の使用を試みます。インストーラによって検出されたデフォルトのJREを使用する必要はありません。インストールされているJava17以降のJREはどれでも使用できます。

Apache Tomcat 11 > User Guide > Tomcat Setup > Windows

また、上の例ではTomcatのインストールディレクトリへ移動し、カレントディレクトリ=Tomcatのインストールディレクトリという状態でコマンド実行していますが、これ以外の場所で実行する場合は、絶対パス指定やPATH設定済であっても、Tomcatのホームを設定する環境変数 CATALINA_HOME が必須となります。

# Tomcat のインストールディレクトリでは起動できる
#(PATHEXTにより拡張子は指定不要)
$ bin\startup
Using CATALINA_BASE:   "C:\Users\...\apache-tomcat-11.0.5"
Using CATALINA_HOME:   "C:\Users\...\apache-tomcat-11.0.5"
Using CATALINA_TMPDIR: "C:\Users\...\apache-tomcat-11.0.5\temp"
Using JRE_HOME:        "C:\Users\...\jdk-23.0.1"
Using CLASSPATH:       "C:\Users\...\apache-tomcat-11.0.5\bin\bootstrap.jar;C:\Users\...\apache-tomcat-11.0.5\bin\tomcat-juli.jar"
Using CATALINA_OPTS:   ""

# 別のディレクトへ移動
$ cd C:\Users\...\workspace

# 絶対パスを指定して実行
# インストールディレクトリ以外で実行する場合は CATALINA_HOME が必要
$ C:\Users\...\apache-tomcat-11.0.5\bin\startup
The CATALINA_HOME environment variable is not defined correctly
This environment variable is needed to run this program

# PATH に Tomcat の bin ディレクトリを追加
$ path %PATH%;C:\Users\...\apache-tomcat-11.0.5\bin

# PATH に追加されていてもインストールディレクトリ以外で実行する場合は
# 環境変数 CATALINA_HOME を定義しておく必要がある
$ startup
The CATALINA_HOME environment variable is not defined correctly
This environment variable is needed to run this program

# 環境変数 CATALINA_HOME を作成
$ set CATALINA_HOME=C:\Users\...\apache-tomcat-11.0.5

# JAVA_HOME 同様に bin ディレクトリは含めずインストールディレクトリを設定する
$ echo %CATALINA_HOME%
C:\Users\...\apache-tomcat-11.0.5

# カレントディレクトリを問わず起動できるようになる
$ startup
Using CATALINA_BASE:   "C:\Users\...\apache-tomcat-11.0.5"
Using CATALINA_HOME:   "C:\Users\...\apache-tomcat-11.0.5"
Using CATALINA_TMPDIR: "C:\Users\...\apache-tomcat-11.0.5\temp"
Using JRE_HOME:        "C:\Users\...\jdk-23.0.1"
Using CLASSPATH:       "C:\Users\...\apache-tomcat-11.0.5\bin\bootstrap.jar;C:\Users\...\apache-tomcat-11.0.5\bin\tomcat-juli.jar"
Using CATALINA_OPTS:   ""

CATALINA_HOME: Represents the root of your Tomcat installation, for example /home/tomcat/apache-tomcat-11.0.0 or C:\Program Files\apache-tomcat-11.0.0.
CATALINA_HOME: 例えば /home/tomcat/apache-tomcat-11.0.0C:\Program Files\apache-tomcat-11.0.0 のように、Tomcatインストールのルートを表します。

Apache Tomcat 11 > User Guide > Introduction > CATALINA_HOME and CATALINA_BASE

例)Eclipse

Eclipseでも、組み込みのJavaではなく、インストール済みのJavaを利用したい場合、類似の設定を行います。直接的に JAVA_HOME という環境変数を利用するわけではありませんが、Javaがインストールされているディレクトリパスを指定し、Eclipseから任意のJavaを利用できるようにするという点で、仕組みとしては同様です。

EclipseにJavaの場所を認識させるため、設定画面から「JRE home」という欄にJavaのパスを設定しますが、この時も JAVA_HOME と同じように、bin ディレクトリは含めず、Javaがインストールされたディレクトリ自体を指すようにします。

具体的な詳細手順は以下に記載しています。

JAVA_HOMEの要点

JAVA_HOME の 概要

  • Java(JDKまたはJRE)のディレクトリの絶対パスを設定した環境変数。
  • 慣例的に「 JAVA_HOME 」という変数名が使用される。

JAVA_HOME の 用途

  • Javaが参照するものではない。
  • 他のプログラムがJavaを利用する際に参照するもの。

JAVA_HOME の 利用例

  • Java( java コマンド )
    • 基本的に JAVA_HOME という環境変数を参照することはない。
    • PATH=...;%JAVA_HOME%\bin;... のように設定されている場合は、
      バージョン変更が容易になるという副次的なメリットがある。
      またこの場合、変数名は必ずしも JAVA_HOME である必要はない。
  • Ant( ant コマンド )
    • 内部でJavaを利用している。(=javaコマンドを認識させる必要がある)
    • PATH または JAVA_HOME のいずれか一方が設定されている必要がある。
      両方が定義されている場合は、環境変数 JAVA_HOME が優先される。
  • Maven( mvn コマンド )
    • 内部でJavaを利用している。(=javaコマンドを認識させる必要がある)
    • PATH または JAVA_HOME のいずれか一方が設定されている必要がある。
      両方が定義されている場合は、環境変数 JAVA_HOME が優先される。
  • Tomcat
    • 内部でJavaを利用している。(=javaコマンドを認識させる必要がある)
    • 環境変数 JAVA_HOME を参照して、利用するJavaの場所を特定している。
      そのため環境変数 PATH の設定は不要で、JAVA_HOME の設定は必須。
    • インストールディレクトリ以外をカレントディレクトリとして起動する場合、
      Tomcatのインストールディレクトリを設定する CATALINA_HOME が必須。
  • Eclipse
    • 直接 JAVA_HOME を利用することは無いものの、
      組み込みでない既存のJavaを利用する場合は、JAVA_HOME 同様、
      Javaのインストールディレクトリを設定画面から登録する。