Java/Kotlin
PR

Gradleでapiが使えないときはjava-libraryプラグインを使う

saratogax
記事内に商品プロモーションを含む場合があります

Gradle の dependencies で api を使おうとしたら、Configuration with name 'api' not found. と怒られて戸惑っていませんか?

原因は、適用しているのが java プラグインで、api を持つ java-library プラグインではないことです。

この記事では、api が使えるケースと使えないケースを実際に検証した結果と、api と implementation の使い分けを紹介します。

最初は Gradle 7.4 で試し、Gradle 9.8.0 でも同じ結果になることを確認しています。

compile や runtime からの置き換えを調べている人は、こちらもあわせてどうぞ。

あわせて読みたい
Gradleのcompileは非推奨なのでimplementationかapiに置き換える
Gradleのcompileは非推奨なのでimplementationかapiに置き換える

Gradleの公式サイトの情報

公式のドキュメントサイトで、compile については以下のように書かれています。

The compile and runtime configurations have been removed with Gradle 7.0. Please refer to the upgrade guide how to migrate to implementation and api configurations`.

API and implementation separation

Gradle 7.0 で完全に削除されたようですね。

implementation または api への置き換えを促されています。

その前までは、以下の定義で compile も利用可能でしたよね。

import org.gradle.api.artifacts.dsl.DependencyHandler

fun DependencyHandler.compile(dependency: Any) {
    add("compile", dependency)
}

apiが利用できないケース

上記の compile はすでに使えなくなっていますが、api についても configurationName に存在しないと怒られます。

fun DependencyHandler.api(dependency: Any) {
    add("api", dependency)
}

api のメソッド利用もリファレンスに存在しない状況です。

api(dependency)

いやいや、api は使えるハズでしょ。

Configuration with name 'api' not found.

Gradle 9.8.0 の Kotlin DSL(build.gradle.kts)で api(...) と書いた場合は、スクリプトのコンパイルの時点で Unresolved reference 'api'. になりました。

implementation はもちろん大丈夫。

implementation(dependency1)
implementation(dependency2)

ということで、よくよくドキュメントを読んでみると以下の 2 つのプラグイン(plugin)の違いということでした。

  • java
  • java-library

確かに java プラグインには api が存在しませんね。

java プラグインを使っているから api のメソッドが参照できなかったわけですね。

plugin("java")

ということで、利用用途に合わせて java と java-library のどちらのプラグインを使うか検討が必要という結論に。

今の build.gradle.kts なら、plugins ブロックで java-library を指定します。

plugins {
    `java-library`
}

Groovy DSL(build.gradle)の場合は次のとおりです。

plugins {
    id 'java-library'
}

Kotlin の場合は kotlin プラグインを使いますが、kotlin-library のような別のプラグインはありません。

Kotlin の JVM プラグイン(2.4.20)で試したところ、java-library を足さなくても api が使えました。

plugin("kotlin")

api と implementation の使い分け

Gradle の公式ドキュメントでは、2 つの違いを次のように説明しています。

The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component.

The Java Library Plugin

api に書いた依存は、そのライブラリを使う側のコンパイルにも見えるようになります。

implementation に書いた依存はライブラリの内部だけで使うものとして扱われ、使う側からは見えません。

公式ドキュメントもできるだけ implementation を使うよう勧めています。

api にするのは、公開しているメソッドの引数や戻り値にその依存の型が出てくる場合です。

まとめ

Gradle の dependencies で api を使うための条件を調べてみました。

何気なく java プラグインを利用していましたが、api を使うには java-library が必要とのこと。

できれば依存関係を辿らなくて済むようにしたいですが、自作のライブラリなど意図的に依存関係を読み込ませたいケースもありそうです。

今回は implementation で依存関係のあるライブラリも参照させて回避しましたが、設計が悩ましいところ・・・。

Gradle のビルドで非推奨の警告が出て困っている人は、こちらもあわせてどうぞ。

あわせて読みたい
「Deprecated Gradle features were used in this build」の原因を調べる方法|IntelliJ対応
「Deprecated Gradle features were used in this build」の原因を調べる方法|IntelliJ対応
ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました