複数の異なるJREがインストールされているマシン上でJavaアプリケーションを動かす場合、パスの記述方法を誤っていると意図していないJRE上でアプリケーションが動いてしまうことがあります。
アプリケーションで動作保証しているJREのバージョンは決めている事がほとんどなので、動作しているJREのバージョンをきちんと把握しておく事はとても大事です。
今回は、Javaアプリケーション内で、動作しているJREを判別する方法を紹介します。
皆さんは、開発したJavaアプリケーションを動かす場合、Javaアプリケーションを動かすサーバやパソコンにJREをインストールしているかと思います。
その際、環境変数にJREのパスを記述したり、もしくは、Javaアプリケーションの起動シェル(バッチ)にJREのパスを記述したり、といった方法をとっているのではないでしょうか。
単純に、1つのバージョンのJREをインストールし、そのサーバやパソコンで動作するアプリケーションはインストールした1つのバージョンのJRE上で動かす場合は問題ないのですが、例えば、1つのサーバやパソコン内で、あるアプリケーションはJava1.7で動かしたいが、あるアプリケーションはJava1.8で動かしたいといったパターンがまれにあります。
その場合、「本当にこのアプリ、Java1.8で動いてるっけ?」って不安になりませんか?
だって、Javaは2つ入っている訳でありまして。。。
こういう心配性な技術者向けに、Javaプログラム内で参照しているJavaのパスを取得する方法を紹介します。
複数のJREがインストールされている環境
サーバ上で10個のアプリケーションが動かす必要があり、そのうち9個はJava1.7で動かす必要があるが、1個はJava1.8で動かす必要がある、といった場面です。
この場合、ほとんどの人が以下のような方法をとるのではないか?
- JREは、1.7と1.8の両方をインストールする。
- 環境変数には、Java1.7のパスを定義する。
- Java1.8で動かす必要があるアプリについてどうにかする。
環境変数にはJava1.7とJava1.8のパスを両方定義しても無意味です。
参照先パスは、先に見つかった方を採用するので、後に定義したJavaのパスは無視されます
Java1.7が採用される環境変数の記述方法
C:\Program Files\Java\jre1.7\bin;C:\Program Files\Java\jre1.8\bin
Java1.8が採用される環境変数の記述方法
C:\Program Files\Java\jre1.8\bin;C:\Program Files\Java\jre1.7\bin
2つ定義するのは無意味なので、環境変数の定義は以下のように記載するのが正解です。
正しい環境変数の定義
C:\Program Files\Java\jre1.7\bin
Java1.7で動くアプリケーションは上記でいいとして、問題はJava1.8で動かす方です。
王道としてはアプリケーションの起動シェルやバッチにJava1.8のパスを定義する方法がメジャーです。
set PATH=C:\Program Files\Java\jre1.8\bin;%PATH%
%PATH%の前にJava1.8のパスを記載するのがポイントです。
環境変数にはJava1.7のパスが定義されているので、%PATH%の後にJava1.8のパスを記載してしまうとJava1.7の方が採用されてしまいます。%PATH%の前にJava1.8のパスを定義することで、Java1.8の方が採用されます。
本当に意図したJREで動いているか?を確認
動かすアプリケーションに以下の試験プログラムを入れてみて、意図したJavaのパスを参照しているかを確認しましょう。
「System.getProperty」を使います。
public class getProperty { public static void main(String[] args){ System.out.println("sun.boot.library.path=" + System.getProperty("sun.boot.library.path")); } }
実行結果は以下になります。
sun.boot.library.path=C:\Program Files\Java\jre1.8\bin
「sun.boot.library.path」がJavaのパスです。
これが、Java1.8になっていればOK。
Javaのプロパティ情報を出力する
Javaのパスを確認してみましたが、Javaのパス以外にもプロパティ情報が存在します。
以下のプログラムでリスト形式で確認できます。
import java.util.Properties; public class getProperty2 { public static void main(String[] args){ Properties props = System.getProperties(); props.list(System.out); } }
実行結果は以下になります。
-- listing properties -- sun.desktop=windows awt.toolkit=sun.awt.windows.WToolkit java.specification.version=12 sun.cpu.isalist=amd64 sun.jnu.encoding=MS932 java.class.path=. java.vm.vendor=Oracle Corporation sun.arch.data.model=64 user.variant= java.vendor.url=https://java.oracle.com/ java.vm.specification.version=12 os.name=Windows 7 sun.java.launcher=SUN_STANDARD user.country=JP sun.boot.library.path=C:\Program Files\Java\jdk-1.8\bin sun.java.command=getProperty jdk.debug=release sun.cpu.endian=little user.home=C:\Users\user user.language=ja sun.stderr.encoding=ms932 java.specification.vendor=Oracle Corporation java.version.date=2019-04-16 java.home=C:\Program Files\Java\jdk1.8 file.separator=\ java.vm.compressedOopsMode=32-bit line.separator= java.vm.specification.vendor=Oracle Corporation java.specification.name=Java Platform API Specification java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironmen user.script= sun.management.compiler=HotSpot 64-Bit Tiered Compilers java.runtime.version=12.0.1+12 user.name=saku path.separator=; os.version=6.1 java.runtime.name=Java(TM) SE Runtime Environment file.encoding=MS932 java.vm.name=Java HotSpot(TM) 64-Bit Server VM java.vendor.url.bug=https://bugreport.java.com/bugreport/ java.io.tmpdir=C:\Users\Temp\ java.version=12.0.1 user.dir=C:\blog\systemProperty os.arch=amd64 java.vm.specification.name=Java Virtual Machine Specification sun.os.patch.level=Service Pack 1 java.library.path=C:\Program Files\Java\jre1.8\bin;... java.vm.info=mixed mode, sharing java.vendor=Oracle Corporation java.vm.version=12.0.1+12 sun.io.unicode.encoding=UnicodeLittle java.class.version=56.0
「sun.boot.library.path」も出力されていますね。
48行目です。
まとめ
いかがでしたでしょうか?
もし、“このアプリって本当に、意図したJavaみてるっけ?”と気になった時は、「System.getProperty」を使ってJavaのパスを確認した方がよいかと思います。
パスの設定が間違っていても、なかなか気が付かなかったりするので、実際にアプリケーションにデバッグブログラムをいれて確認すると安心ですね。
それではまた!