JAVAC warning「source/target value 8 is obsolete」の原因と解消手順(.NET MAUI・JDK 21対応ガイド)

.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 SDKdotnet --info最新の LTS / 現行版SDK が古いと Android Workload も古いままになりがち
Android/Maui Workloaddotnet workload list更新済み更新で内部のビルドチェーンが新しくなる
JDKjava -version17 か 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 別の設定例

OSJDK 17 の準備JDK の切り替え(推奨手順)
WindowsJDK 17(Temurin / Microsoft Build of OpenJDK など)をインストールシステムの「環境変数」で JAVA_HOME を JDK 17 のパスに設定 PATH に %JAVA_HOME%\bin を先頭付近に追加 プロジェクト側で確実に固定したい場合は csproj に下記を記述
macOSbrew install --cask temurin17 などで導入export JAVA_HOME=$(/usr/libexec/java_home -v 17) echo $JAVA_HOME で 17 系を指しているか確認
Linuxapt / 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 バージョンにより名称の有無が異なるため、まずは以下のいずれかで試し、ビルドログに反映されるか確認してください)。

&lt;Project&gt;
  &lt;PropertyGroup&gt;
    &lt;!-- どちらか片方で十分。効く方を採用 --&gt;
    &lt;JavacAdditionalArguments&gt;-Xlint:-options&lt;/JavacAdditionalArguments&gt;
    &lt;JavaCompilerFlags&gt;-Xlint:-options&lt;/JavaCompilerFlags&gt;
  &lt;/PropertyGroup&gt;
&lt;/Project&gt;

反映確認のコツ

  • dotnet build -v:diag のログに javac のコマンドラインが出ます。そこに -Xlint:-options が含まれていれば成功です。
  • 反映されない場合は、プロパティ名を変えるか、方法 B または D を選びましょう。

方法 D:-source/-target を 11 以上へ引き上げる

プロジェクト側で Java のソース/ターゲットバージョンを上げる方法です。JDK 21 以上でも警告が出なくなります。

&lt;Project&gt;
  &lt;PropertyGroup&gt;
    &lt;JavaSourceVersion&gt;11&lt;/JavaSourceVersion&gt;
    &lt;JavaTargetVersion&gt;11&lt;/JavaTargetVersion&gt;
  &lt;/PropertyGroup&gt;
&lt;/Project&gt;

注意点

  • 依存している AAR/JAR や一部のツールチェーンが Java 8 に縛られている場合、稀にコンパイルや D8 変換で相性問題が出ます。ビルドや起動テストを十分に行った上で運用に入れてください。
  • ビルドで「major version 55 以上に未対応」などのエラーに遭遇したら、方法 B(JDK 17 固定)もしくは方法 A(Workload 更 新)を優先しましょう。

おすすめの意思決定フロー

  1. まず方法 A(Workload 更新)を実行し、クリーンビルドで様子を見る。
  2. 短期的に静めたいなら 方法 B(JDK 17 固定)を採用。CI では特に有効。
  3. ログの静音化だけが目的なら 方法 C(-Xlint:-options)を限定運用。
  4. プロジェクトの制約が許すなら 方法 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 固定)

&lt;Project&gt;
  &lt;PropertyGroup&gt;
    &lt;JavaSdkDirectory&gt;$(JAVA_HOME)&lt;/JavaSdkDirectory&gt;
    &lt;!-- 参考:抑制したい場合だけ有効化
    &lt;JavacAdditionalArguments&gt;-Xlint:-options&lt;/JavacAdditionalArguments&gt;
    --&gt;
  &lt;/PropertyGroup&gt;
&lt;/Project&gt;

プロジェクトに貼るテンプレート(Java 11 へ引き上げ)

&lt;Project&gt;
  &lt;PropertyGroup&gt;
    &lt;JavaSourceVersion&gt;11&lt;/JavaSourceVersion&gt;
    &lt;JavaTargetVersion&gt;11&lt;/JavaTargetVersion&gt;
  &lt;/PropertyGroup&gt;
&lt;/Project&gt;

開発マシンの点検コマンド

# Java の所在確認
where java      # Windows
which java      # macOS / Linux

# 実際のバージョン

java -version
javac -version

# .NET / Workload

dotnet --info
dotnet workload list 

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次