Une note d'étude sur compile
, ʻapi, ʻimplementation
spécifiée par dependencies
dans Gradle.
Java Library Plugin a été ajouté dans Gradle 3.4 (https://docs.gradle.org/3.4/release-notes. (html # the-java-library-plugin), il semble que l'utilisation de compile
with dependencies
était obsolète (aussi runtime
, testCompile
, testRuntime
).
Dans 4.7 Description du plug-in Java, il est écrit comme obsolète
.
(Documentation 4.6 ne dit pas «obsolète», mais c'est définitivement obsolète Récemment?)
Il est recommandé d'utiliser ʻimplementation et ʻapi
à la place.
La mise en oeuvre
Structure du projet
|-settings.gradle
|-build.gradle
|
|-foo/
| |-build.gradle
| `-src/main/java/foo/
| `-Foo.java
|
`-bar/
|-build.gradle
`-src/main/java/bar/
`-Bar.java
/settings.gradle
include 'foo', 'bar'
/build.gradle
subprojects {
apply plugin: 'java'
sourceCompatibility = 10
targetCompatibility = 10
compileJava.options.encoding = 'UTF-8'
repositories {
mavenCentral()
}
}
/bar/build.gradle
dependencies {
compile 'org.apache.commons:commons-lang3:3.7'
}
Bar.java
package bar;
import org.apache.commons.lang3.RandomStringUtils;
public class Bar {
public void hello() {
System.out.println("Bar: " + RandomStringUtils.random(10, "0123456789"));
}
}
/foo/build.gradle
apply plugin: 'application'
mainClassName = 'foo.Foo'
dependencies {
compile project(':bar')
}
Foo.java
package foo;
import bar.Bar;
import org.apache.commons.lang3.RandomStringUtils;
public class Foo {
public static void main(String... args) {
new Bar().hello();
System.out.println("Foo: " + RandomStringUtils.random(10, "0123456789"));
}
}
--Comprend deux sous-projets, foo
et bar
--bar
dépend de commons-lang3
--foo
dépend du projet bar
--Chaque projet utilise commons-lang3
** Résultat d'exécution **
> gradle :foo:run
Bar: 3803159716
Foo: 6423224304
La mise en oeuvre
/bar/build.gradle
dependencies {
implementation 'org.apache.commons:commons-lang3:3.7'
}
/foo/build.gradle
apply plugin: 'application'
mainClassName = 'foo.Foo'
dependencies {
implementation project(':bar')
}
** Résultat d'exécution **
> gradle :foo:run
...\foo\src\main\java\foo\Foo.java:4:Erreur:Organisation du package.apache.commons.lang3 n'existe pas
import org.apache.commons.lang3.RandomStringUtils;
^
...\foo\src\main\java\foo\Foo.java:10:Erreur:Impossible de trouver le symbole
System.out.println("Foo: " + RandomStringUtils.random(10, "0123456789"));
^
symbole:Variable RandomStringUtils
endroit:Classe Foo
2 erreurs
...
Relation de dépendance
# compile
[foo] --compile--> [bar] --compile--> [commons-lang3]
[foo] - ok -> [bar] - ok -> [commons-lang3]
| ^
| |
+------------ ok ---------------+
# implementation
[foo] --implementation--> [bar] --implementation--> [commons-lang3]
[foo] - ok -> [bar] - ok -> [commons-lang3]
| x
| |
+------------ ng ---------------+
--La dépendance spécifiée par compile
est propagée
commons-lang3
dans compile
dans le projet bar
, et que vous spécifiez le projet bar
comme dépendance dans le projet foo
, le projet foo
dépend également de commons-lang3
. Devenir
--La dépendance spécifiée par ʻimplementation` n'est pas propagéecommons-lang3
avec ʻimplementation dans le projet
bar, le projet
foo dépend de
commons-lang3même si vous spécifiez le projet
bar comme dépendance dans le projet
foo. Non (le projet
foo ne peut pas utiliser
commons-lang3`)La mise en oeuvre
/bar/build.gradle
apply plugin: 'java-library'
dependencies {
api 'org.apache.commons:commons-lang3:3.7'
}
** Résultat d'exécution **
$ gradle :foo:run
Bar: 7783742303
Foo: 6741510207
/bar/build.gradle
apply plugin: 'java-library'
dependencies {
api 'org.apache.commons:commons-lang3:3.7'
}
--Pour propager des dépendances comme compile
, spécifiez les dépendances avec ʻapi --ʻApi
devient disponible en ajoutant Java Library Plugin
java-library
La documentation officielle explique que l'utilisation de ʻimplementation au lieu de
compiler` présente les avantages suivants:
En bref, l'utilisation de compile
posait les problèmes suivants.
―― Puisque toutes les dépendances sont propagées de manière transitoire, les dépendances se sont étendues inutilement.
En définissant cela avec ʻimplementation, il est possible d'empêcher l'expansion inutile des dépendances et de ne faire la transition que les dépendances qui sont vraiment nécessaires avec ʻapi
.
Il y a aussi l'avantage que la fréquence de recompilation peut être réduite en empêchant la "mise en œuvre" de propager des dépendances.
Voici mon opinion personnelle.
--Déclaré de manière basique avec ʻimplementation --Publiez côté utilisateur avec ʻapi
seulement quand il est absolument nécessaire de le propager côté utilisateur
――Si possible, je pense que ce serait mieux si vous pouviez éliminer la dépendance directe à la bibliothèque que vous utilisez en l'enveloppant dans votre propre API.
--Facile à remplacer les bibliothèques
configuration |
Propagation des dépendances | Plug-in défini |
---|---|---|
compile |
Faire | Java Plugin |
implementation |
ne pas faire | Java Plugin |
api |
Faire | Java Library Plugin |