.NET MAUI/.NET for Android の更新後、JDK 21 以上の環境でビルドすると JAVAC : warning : [options] source/target value 8 is obsolete が出て気になる――そんな相談をよく受けます。本記事では「原因の正体」と「安全に静める4つの選択肢」を、現場でそのまま使える具体手順・チェックリスト・CI設定例まで含めて、丁寧に解説します。
症状(ビルドログ)
JAVAC : warning : [options] source value 8 is obsolete and will be removed in a future release
JAVAC : warning : [options] target value 8 is obsolete and will be removed in a future release
JAVAC : warning : [options] To suppress warnings about obsolete options, use -Xlint:-options.
ビルド自体は成功するものの、JDK 21 以上で -source 8 / -target 8 を指定して javac が呼ばれると上記の警告が出ます。
なぜ起きるのか(背景の整理)
- JDK 21 以降の
javacでは、Java 8(-source/-target 8)が「旧式(obsolete)」扱いになりました。将来のリリースで削除される可能性があるため、警告を出して注意喚起しています。 - .NET MAUI(.NET for Android)は、ビルド過程で Java のスタブコードを
javacでコンパイルします。このとき既定の互換性のために-source 8 -target 8を渡すケースがあり、そこに JDK 21 以上が組み合わさると当該の警告が現れます。 - この警告はエラーではなくビルドは成功します。アプリの実行・配布に直ちに支障はありませんが、CI のログをノイズで埋めたり、将来の JDK でビルド不可になるリスクを早めに可視化してくれています。
対象範囲(どのプラットフォームで出る?)
- Android 向けビルドのみで発生します(
net8.0-android/net9.0-androidなど)。 - iOS / macOS / Windows 向けの MAUI ビルドでは
javacを使わないため、この警告は出ません。
まずは環境を確認
警告の有無や対処方針は「使用中の .NET SDK / Workload」と「JDK のバージョン」に左右されます。以下のコマンドで実態を把握しましょう。
# .NET SDK・ランタイムの情報
dotnet --info
# インストール済み Workload の一覧(MAUI/Android を含む)
dotnet workload list
# Java のバージョン(実行中に使われる JDK)
java -version
javac -version
| チェック項目 | 見る場所 | OK の目安 | 補足 |
|---|---|---|---|
| .NET SDK | dotnet --info | 最新の LTS / 現行版 | SDK が古いと Android Workload も古いままになりがち |
| Android/Maui Workload | dotnet workload list | 更新済み | 更新で内部のビルドチェーンが新しくなる |
| JDK | java -version | 17 か 21 以上 | 21 以上で警告が出やすい/17 に戻すと出ない |
解決方針の比較(クイックサマリ)
| 方法 | 狙い | 効果 | おすすめ度 |
|---|---|---|---|
| A. MAUI/Android Workload を最新化 | 内部のビルドチェーン(javac 呼び出し条件など)の更新 | 新しい設定で警告が出なくなる/将来の非互換にも強い | 最優先(推奨) |
| B. JDK を 17 系に固定 | JDK 17 では -source 8 が obsolete 扱いではない | 警告を即時解消、影響範囲が読みやすい | 短期回避として有効 |
C. 警告だけ抑制(-Xlint:-options) | ログの静音化 | ビルドは継続、根本条件はそのまま | 限定状況(CI など)で |
D. -source/-target を 11 以上へ引き上げ | プロジェクト側で javac の指定を上げる | JDK 21 以上でも警告が出ない | 環境により追加検証が必要 |
方法 A:MAUI / Android Workload を最新化(推奨)
まずは公式のパスに従って Workload を最新化します。これにより、ツールチェーンの既定値や依存コンポーネントの組み合わせが更新され、警告が自然に消える(または将来的に消える)可能性が高まります。
# 現在のワークロードを確認
dotnet workload list
# ワークロードを更新(Linux/macOS は sudo 推奨)
sudo dotnet workload update
# 念のためのクリーンアップ
dotnet clean
dotnet nuget locals all --clear
# プロジェクト直下の bin/obj を削除して再ビルド
ポイント
- Visual Studio を併用している場合は、VS 自体の更新(拡張の MAUI/Android ツール含む)も合わせて行うと整合が取れます。
- 更新後に一度 クリーンビルドし、ログから依然として
-source 8が渡されていないかを確認しましょう。
方法 B:JDK を 17 系に固定(短期回避)
どうしても今すぐ警告を消したい場合は、ビルドで使う JDK を 17 に固定します。JDK 17 では Java 8 は obsolete 扱いではないため、同じ -source 8 / -target 8 でも警告は出ません。
OS 別の設定例
| OS | JDK 17 の準備 | JDK の切り替え(推奨手順) |
|---|---|---|
| Windows | JDK 17(Temurin / Microsoft Build of OpenJDK など)をインストール | システムの「環境変数」で JAVA_HOME を JDK 17 のパスに設定 PATH に %JAVA_HOME%\bin を先頭付近に追加 プロジェクト側で確実に固定したい場合は csproj に下記を記述 |
| macOS | brew install --cask temurin17 などで導入 | export JAVA_HOME=$(/usr/libexec/java_home -v 17) echo $JAVA_HOME で 17 系を指しているか確認 |
| Linux | apt / dnf などで openjdk-17 を導入 | sudo update-alternatives --config java で 17 を選択 export JAVA_HOME=/usr/lib/jvm/java-17-… |
プロジェクトの MSBuild で JDK を固定するには、次のように csproj(または Directory.Build.props)に記述します。
<Project>
<PropertyGroup>
<!-- JDK 17 のインストール先に合わせて変更 -->
<JavaSdkDirectory>$(JAVA_HOME)</JavaSdkDirectory>
</PropertyGroup>
</Project>
優先度の目安(どれが効く?)
| 指定場所 | 例 | 優先度 | 備考 |
|---|---|---|---|
| プロジェクト(MSBuild) | <JavaSdkDirectory> | 高 | CI でも再現性が高い |
| IDE の設定 | Visual Studio の Java SDK ロケーション | 中 | 開発機ごとに差異が出やすい |
| 環境変数 | JAVA_HOME / PATH | 中 | シェル・ユーザー単位で変化 |
CI での固定例(GitHub Actions)
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Workload restore
run: dotnet workload restore
- name: Build
run: dotnet build -c Release
方法 C:警告だけ抑制する(-Xlint:-options)
根本条件はそのままに、ログ出力だけを静かにする手です。本番問題の見落としを防ぐため、CI のみの適用など限定運用を推奨します。
javac に追加引数を渡すには、MSBuild プロパティを用います(環境や SDK バージョンにより名称の有無が異なるため、まずは以下のいずれかで試し、ビルドログに反映されるか確認してください)。
<Project>
<PropertyGroup>
<!-- どちらか片方で十分。効く方を採用 -->
<JavacAdditionalArguments>-Xlint:-options</JavacAdditionalArguments>
<JavaCompilerFlags>-Xlint:-options</JavaCompilerFlags>
</PropertyGroup>
</Project>
反映確認のコツ
dotnet build -v:diagのログにjavacのコマンドラインが出ます。そこに-Xlint:-optionsが含まれていれば成功です。- 反映されない場合は、プロパティ名を変えるか、方法 B または D を選びましょう。
方法 D:-source/-target を 11 以上へ引き上げる
プロジェクト側で Java のソース/ターゲットバージョンを上げる方法です。JDK 21 以上でも警告が出なくなります。
<Project>
<PropertyGroup>
<JavaSourceVersion>11</JavaSourceVersion>
<JavaTargetVersion>11</JavaTargetVersion>
</PropertyGroup>
</Project>
注意点
- 依存している AAR/JAR や一部のツールチェーンが Java 8 に縛られている場合、稀にコンパイルや D8 変換で相性問題が出ます。ビルドや起動テストを十分に行った上で運用に入れてください。
- ビルドで「major version 55 以上に未対応」などのエラーに遭遇したら、方法 B(JDK 17 固定)もしくは方法 A(Workload 更 新)を優先しましょう。
おすすめの意思決定フロー
- まず方法 A(Workload 更新)を実行し、クリーンビルドで様子を見る。
- 短期的に静めたいなら 方法 B(JDK 17 固定)を採用。CI では特に有効。
- ログの静音化だけが目的なら 方法 C(-Xlint:-options)を限定運用。
- プロジェクトの制約が許すなら 方法 D(source/target を 11+)を試す。問題があればすぐに B へロールバック。
トラブルシューティング(うまくいかない時は)
- bin/obj の完全削除:プロジェクト直下の
bin/objを消し、再ビルド。 - NuGet キャッシュのクリア:
dotnet nuget locals all --clear。 - どの JDK が使われているかの特定:
dotnet build -v:diagでjavacの呼び出し行を検索し、パスと引数を確認。 - JDK の混在を解消:
where java(Win) /which java(Unix系)で複数の Java が PATH に現れないか確認。 - MSBuild の優先度:
<JavaSdkDirectory>を明示すれば IDE やJAVA_HOMEより優先し、多くの「なぜか違う JDK を掴む」問題を避けられます。
実務でのベストプラクティス
- CI/CD は再現性重視:アクション/パイプラインの最初で JDK と .NET SDK を明示固定し、Workload を
restore。この 3点を固定するだけで環境差の不具合は激減します。 - ローカル開発は自動更新+固定の併用:普段は Workload を定期更新し、突発的なビルドノイズが増えたら一時的に JDK を 17 に固定して開発継続、後で検証の上で戻す。
- 警告は“将来の非互換”のアラート:抑制だけで済ませず、計画的に「source/target を 11+」へ移行できるか、依存関係を棚卸ししておきましょう。
詳細解説:各方法のメリット/デメリット
| 方法 | メリット | デメリット | 向いているケース |
|---|---|---|---|
| A. Workload 更新 | 将来の変更にも追従しやすい/手戻りが少ない | 更新の都度の検証が必要/一時的に別の警告が出る可能性 | 長期運用のプロダクト、複数メンバーがいるチーム |
| B. JDK 17 固定 | 即効性が高い/影響範囲が読みやすい | JDK 21 新機能を使う開発と両立しにくい | CI の安定化、緊急回避、リリース前の一時対応 |
| C. 警告抑制 | ログが静か/他の重要警告を見つけやすくなる | 根本は未解決/将来の非互換の検知が遅れる | 一時的なログクリーン化、既知の安全範囲での運用 |
| D. source/target を 11+ | JDK 21 以上でも警告ゼロ/将来の Java バージョン移行が楽 | 依存物によっては相性検証が必要 | 自前 Java コードが少なく、移行影響が小さいプロジェクト |
現場で役立つスニペット集
プロジェクト直下で使うメンテ系コマンド
# bin/obj を消す(PowerShell)
Get-ChildItem -Directory -Filter bin, obj -Recurse | Remove-Item -Recurse -Force
# Unix 系
find . -type d -name bin -o -name obj | xargs rm -rf
MSBuild のバイナリログで原因追跡
# バイナリログを採取
dotnet build -bl
# msbuild.binlog を MSBuild Structured Log で開き、
# "javac" タスクのコマンドラインと使用 JDK を確認
GitLab CI の例
image: mcr.microsoft.com/dotnet/sdk:8.0
stages: [build]
build:
stage: build
script:
- apt-get update && apt-get install -y openjdk-17-jdk
- export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
- export PATH="$JAVA_HOME/bin:$PATH"
- dotnet workload restore
- dotnet build -c Release
誤解しがちなポイント
- 「Gradle をいじれば解決する」わけではありません:.NET for Android は
javacを MSBuild タスクから直接呼ぶ構成であり、gradle.propertiesの設定が効かないケースが一般的です。まずは本記事の方法 A〜D を優先してください。 - 警告は“ビルド失敗の予兆”ではない:現時点ではビルド成功・実行可能です。ただし将来の JDK で削除された際に初めて失敗へ変わる可能性があるため、恒久対応(A または D)を並行して検討しましょう。
最終まとめ
- 根本原因:JDK 21 以上で
-source 8 / -target 8が「旧式」扱い。 - 第一選択:Workload を最新化(方法 A)。
- 短期回避:JDK 17 に固定(方法 B)。
- ログ静音:
-Xlint:-optionsを追加(方法 C)。 - 将来を見据えた調整:source/target を 11+ へ(方法 D、要検証)。
以上の手順を順番に試せば、ほとんどの環境で「JAVAC : warning : [options] source/target value 8 is obsolete」を確実にコントロールできます。チーム・CI とローカルで同じ方針を共有し、継続的に Workload を更新しておくのが、長期的な安定運用への近道です。
付録:実運用サンプル(テンプレート)
プロジェクトに貼るテンプレート(JDK 17 固定)
<Project>
<PropertyGroup>
<JavaSdkDirectory>$(JAVA_HOME)</JavaSdkDirectory>
<!-- 参考:抑制したい場合だけ有効化
<JavacAdditionalArguments>-Xlint:-options</JavacAdditionalArguments>
-->
</PropertyGroup>
</Project>
プロジェクトに貼るテンプレート(Java 11 へ引き上げ)
<Project>
<PropertyGroup>
<JavaSourceVersion>11</JavaSourceVersion>
<JavaTargetVersion>11</JavaTargetVersion>
</PropertyGroup>
</Project>
開発マシンの点検コマンド
# Java の所在確認
where java # Windows
which java # macOS / Linux
# 実際のバージョン
java -version
javac -version
# .NET / Workload
dotnet --info
dotnet workload list

コメント