* 目次 [#ieb3ac2b]
#contents
* Windows環境でJavaバージョンを制御する方法 - Java Shimと環境変数の活用 [#u3626865]

** はじめに [#uab10f46]

Windowsで開発を行う際、複数のJavaバージョンを使い分ける必要があることがあります。従来の環境変数(JAVA_HOME)による制御方法は広く知られていますが、Oracle JDK 9以降で導入された「Java Shim」の仕組みを理解し活用することで、より柔軟にJava環境を管理できます。特に、IDEが特定のバージョンを使用する一方で、コマンドラインでは別のバージョンが使われるという状況を解決するには、両方のアプローチを理解することが重要です。この記事では、環境変数の設定だけでなく、Java Shimを直接制御する方法も含めて、Windowsでシステム全体のJavaバージョンを変更する方法について説明します。

** 問題の背景 [#qb702c42]

Windowsでは、Oracle JDK 9以降のインストール時に「Java Shim」と呼ばれる比較的新しい仕組みが導入されました。これはJava 8時代には存在しなかった仕組みで、多くの開発者を混乱させる原因となっています。

Java Shimは以下のディレクトリにシンボリックリンクまたは実行ファイル(shimconsole.exe)を配置します:

 C:\Program Files\Common Files\Oracle\Java\javapath

このディレクトリはシステムのPATH環境変数の先頭近くに自動的に追加されるため、`java`コマンドを実行すると、このディレクトリ内のファイルが最初に見つかります。これにより、システムにインストールされている最新のJavaバージョンが自動的に使用されるようになっています。

この仕組みは便利な一方で、以下のような問題を引き起こします:

1. **複数バージョンの管理が困難**:特定のプロジェクトで特定のJavaバージョンを使いたい場合に問題が生じます。

2. **IDEとコマンドラインの不一致**:Windsurfなどの最新のIDEはデフォルトでJava 21などの新しいバージョンを使用するよう設定されていることがありますが、コマンドラインではJava Shimによって別のバージョン(例:Java 17)が使用されることがあります。

3. **PowerShellでの挙動**:PowerShellはWindows 10以降のデフォルトシェルとなっていますが、環境変数の解決方法がコマンドプロンプトと異なるため、予期しない動作が発生することがあります。

これらの問題により、「IDEでは動くのにコマンドラインでは動かない」といった状況が発生し、開発者を悩ませることになります。

** 現在のJava環境を確認する [#f119873f]

まず、現在使用されているJavaのバージョンと場所を確認しましょう:

 # Javaのバージョンを確認
 java -version
 
 # Javaの実行ファイルの場所を確認
 Get-Command java | Format-List
 
 # Java Shimの内容を確認
 Get-Item "C:\Program Files\Common Files\Oracle\Java\javapath\*.exe"
 
 # JAVA_HOME環境変数を確認
 echo $env:JAVA_HOME

** Javaバージョンを変更する方法 [#e25308f3]

*** 方法1: 環境変数を設定する(推奨) [#r3b518da]

1. **JAVA_HOME環境変数を設定**:
   [Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\path\to\your\java\version", "Machine")

2. **PATHの先頭にJavaのbinディレクトリを追加**:
   $path = [Environment]::GetEnvironmentVariable("Path", "Machine")
   $java21bin = "%JAVA_HOME%\bin"
   if ($path -notlike "*$java21bin*") {
       [Environment]::SetEnvironmentVariable("Path", "$java21bin;$path", "Machine")
   }

3. **システムを再起動**または新しいコマンドプロンプトを開く

4. **変更を確認**:
   echo $env:JAVA_HOME
   java -version

*** 方法2: Java Shimを更新する(上級者向け) [#e676f538]

1. **バックアップディレクトリを作成**:
   New-Item -ItemType Directory -Path "C:\Program Files\Common Files\Oracle\Java\javapath_backup" -Force

2. **既存のファイルをバックアップ**:
   Copy-Item "C:\Program Files\Common Files\Oracle\Java\javapath\*.exe" -Destination "C:\Program Files\Common Files\Oracle\Java\javapath_backup\"

3. **既存のShimファイルを削除**:
   Remove-Item "C:\Program Files\Common Files\Oracle\Java\javapath\java.exe"
   Remove-Item "C:\Program Files\Common Files\Oracle\Java\javapath\javac.exe"
   Remove-Item "C:\Program Files\Common Files\Oracle\Java\javapath\javaw.exe"
   Remove-Item "C:\Program Files\Common Files\Oracle\Java\javapath\jshell.exe"

4. **新しいJavaバージョンへのシンボリックリンクを作成**:
   $javaPath = "C:\path\to\your\java\version\bin"
   New-Item -ItemType SymbolicLink -Path "C:\Program Files\Common Files\Oracle\Java\javapath\java.exe" -Target "$javaPath\java.exe"
   New-Item -ItemType SymbolicLink -Path "C:\Program Files\Common Files\Oracle\Java\javapath\javac.exe" -Target "$javaPath\javac.exe"
   New-Item -ItemType SymbolicLink -Path "C:\Program Files\Common Files\Oracle\Java\javapath\javaw.exe" -Target "$javaPath\javaw.exe"
   New-Item -ItemType SymbolicLink -Path "C:\Program Files\Common Files\Oracle\Java\javapath\jshell.exe" -Target "$javaPath\jshell.exe"

5. **システムを再起動**

** IDEでのJava設定 [#n0e316d4]

*** Windsurfの場合 [#w0f32179]

Windsurfでは、`settings.json`ファイルに以下の設定を追加することで、特定のJavaバージョンを使用できます:

 "java.home": "C:\\path\\to\\your\\java\\version",
 "java.jdt.ls.java.home": "C:\\path\\to\\your\\java\\version",
 "java.import.gradle.java.home": "C:\\path\\to\\your\\java\\version"

** 注意事項 [#r6e6dd31]

1. **Java更新プログラムによる上書き**:Javaの更新プログラムをインストールすると、Java Shimが上書きされる可能性があります。その場合は再度設定が必要です。

2. **管理者権限**:これらの操作には管理者権限が必要です。

3. **システム全体への影響**:これらの変更はシステム全体に影響します。特定のアプリケーションが特定のJavaバージョンに依存している場合、問題が発生する可能性があります。

** まとめ [#t3e2a5bf]

Windowsで複数のJavaバージョンを管理するには、環境変数の設定またはJava Shimの更新という2つの主要な方法があります。環境変数の設定は比較的安全で簡単な方法ですが、Java Shimの更新はより直接的な方法です。どちらの方法も、システムの再起動後に有効になります。

開発環境では、プロジェクトごとに異なるJavaバージョンが必要な場合もあるため、これらの方法を理解しておくと便利です。






* PowerShellでJavaとMavenのバージョン不一致を解決する方法 [#t5aa668d]

** はじめに [#k14d9ac2]

Windowsの開発環境では、PowerShellとGit Bashなど異なるシェル環境で、異なるJavaバージョンが使用されることがあります。特に、システム全体ではJava 17が設定されている一方で、IDEではJava 21を使用しているような状況では、コマンドラインでのビルドが失敗する原因となります。この記事では、PowerShellでJava 21を使用してMavenプロジェクトをビルドする方法について説明します。

** 問題の症状 [#y000642d]

以下のような症状が発生することがあります:

1. Git Bashではビルドが成功するが、PowerShellでは失敗する

2. IDEでは問題なくコンパイルできるが、コマンドラインでは失敗する

3. `java -version`コマンドでは正しいバージョンが表示されるが、Mavenは別のバージョンを使用している

** 原因の特定 [#jd82fd0d]

まず、現在の環境を確認しましょう:

 # Javaのバージョンを確認
 java -version
 
 # Mavenが使用しているJavaを確認
 mvn -version

上記のコマンドで、以下のような出力が得られる場合、Mavenが異なるJavaバージョンを使用していることがわかります:

* java -version の出力 [#gb1669a4]
 openjdk version "21.0.6" 2025-01-21 LTS
 OpenJDK Runtime Environment Temurin-21.0.6+7 (build 21.0.6+7-LTS)
 OpenJDK 64-Bit Server VM Temurin-21.0.6+7 (build 21.0.6+7-LTS, mixed mode, sharing)
 
* mvn -version の出力 [#p0a45028]
 Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
 Maven home: C:\dev\apps\apache-maven-3.9.9
 Java version: 17.0.11, vendor: Oracle Corporation, runtime: C:\Program 
 Files\Java\jdk-17
 Default locale: ja_JP, platform encoding: MS932
 OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

** 解決方法 [#e05d1384]

*** 1. 一時的な解決方法 [#zc6267b5]

PowerShellセッションで以下のコマンドを実行することで、そのセッション内でJava 21を使用するようになります:

 # JAVA_HOME環境変数を設定
 $env:JAVA_HOME="C:\path\to\your\java21"
 
 # PATHの先頭にJava 21のbinディレクトリを追加
 $env:PATH="$env:JAVA_HOME\bin;$env:PATH"
 
 # 設定を確認
 java -version
 mvn -version

これで、PowerShellセッション内でMavenがJava 21を使用するようになります。ただし、この設定はPowerShellを閉じると失われます。

*** 2. PowerShellプロファイルに追加する方法 [#ud453780]

毎回コマンドを入力するのは面倒なので、PowerShellプロファイルに設定を追加することで、PowerShellを起動するたびに自動的に設定されるようにできます:

1. PowerShellプロファイルの場所を確認:
   echo $PROFILE

2. プロファイルファイルを編集(存在しない場合は作成):
   if (!(Test-Path -Path $PROFILE)) {
     New-Item -ItemType File -Path $PROFILE -Force
   }
   notepad $PROFILE

3. 以下の内容を追加:
   # Java 21を使用するための設定
   $env:JAVA_HOME="C:\path\to\your\java21"
   $env:PATH="$env:JAVA_HOME\bin;$env:PATH"

4. PowerShellを再起動して設定を反映させる

*** 3. Mavenの設定ファイルを編集する方法 [#a3b11ffd]

`~/.m2/settings.xml`または`${maven.home}/conf/settings.xml`に以下のような設定を追加することで、Mavenが特定のJavaバージョンを使用するように指定できます:

 <profiles>
   <profile>
     <id>jdk-21</id>
     <activation>
       <activeByDefault>true</activeByDefault>
     </activation>
     <properties>
       <maven.compiler.source>21</maven.compiler.source>
       <maven.compiler.target>21</maven.compiler.target>
       <maven.compiler.release>21</maven.compiler.release>
       <java.home>C:\path\to\your\java21</java.home>
     </properties>
   </profile>
 </profiles>

*** 4. MAVEN_OPTS環境変数を設定する方法 [#i0a6f160]

MAVEN_OPTS環境変数を設定することで、Mavenが使用するJavaを指定することもできます:

 $env:MAVEN_OPTS="-Djava.home=C:\path\to\your\java21"

これをPowerShellプロファイルに追加することで、永続的に設定できます。

** 実際の例 [#rb9820ae]

以下は、Windsurfが使用するJava 21を使ってMavenビルドを行う例です:

 # 環境変数を設定せずにビルドを実行(失敗する)
 mvn clean compile
 
 # 環境変数を設定してビルドを実行(成功する)
 $env:JAVA_HOME="C:\Users\k-hayashi\AppData\Roaming\Windsurf\User\globalStorage\pleiades.java-extension-pack-jdk\java\21"
 $env:PATH="$env:JAVA_HOME\bin;$env:PATH"
 mvn clean compile

** まとめ [#cd606911]

PowerShellでJavaとMavenのバージョン不一致を解決するには、以下の方法があります:

1. セッション内で一時的に環境変数を設定する

2. PowerShellプロファイルに環境変数設定を追加する

3. Mavenの設定ファイルを編集する

4. MAVEN_OPTS環境変数を設定する

これらの方法を組み合わせることで、異なるシェル環境でも一貫したJavaバージョンを使用できるようになります。

** 関連情報 [#f3e6e261]

- [Windows環境でJavaバージョンを制御する方法](./windows-java-path-configuration.md)
- [Maven公式ドキュメント - JDKの設定](https://maven.apache.org/guides/mini/guide-using-toolchains.html)
- [PowerShellプロファイルの詳細](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_profiles)


*** 2025/04/23追記 [#l74a48e7]
上記で対応できていないようになってしまった。
latestを使うようになっている?
 AppData\Roaming\Windsurf\User\globalStorage\pleiades.java-extension-pack-jdk\java\latest
を使うようになっている?

plantumlが動かなくなった!?
トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS