Java Library Plugin

I am working on decomposing a large java application which uses the java library plugin. Some of the confusion I have is with api vs. implementation. I have read the documentation but I fail to have clarity on the following.

  1. If Module M depends on A, which depends on B (api), and M only uses B in order to use A. Our understanding is B is NOT explicitly added to the dependences of Module M (sort of the point of api). Is this agreed upon? Is there a way to detect this VIA gradle today?

  2. If Module A depends on Module B for API reasons ONLY, and then starts using Module B for implementation purposes in the future, should you list both api and implementation for correctness? Why or why not?

  3. Is there some mechanism that exists to verify the validity of the build.gradle files in terms of how the classes are used? e.g. unnecessary api dependencies that COULD/SHOULD be implementation OR vice versa?

  4. What about package private classes across modules? :m → :a where the same package is in both modules, do we need to ensure that all classes in :a that are in the same package follow the same rules as IF the class is module :m?
    ClassA is package private and in module A and uses ClassX for its api (in module X). Does A have an api dependency on X or NOT?

Actually, it is rather simple.

api is a superset of implementation, so if you declared an api dependency, implementation for the same dependency is implied and is not necessary separately, would even be unclean to do so.

If something is only used as implementation detail, so for example in signatures of private methods, or only in method bodies, it belongs to implementation. If something is used in the public API like as superclass, return type, or parameter type, it belongs to api.

A plugin to get the dependency declarations right is GitHub - autonomousapps/dependency-analysis-gradle-plugin: Gradle plugin for JVM projects written in Java, Kotlin, Groovy, or Scala; and Android projects written in Java or Kotlin. Provides advice for managing dependencies and other applied plugins it will tell you which dependencies should be declared differently or are unused according to the best practices you mentioned.

Regarding the package-private part of the question, you should strongly consider whether you really want to have the same package in multiple projects. Such split-package situations are for example strictly forbidden when using JPMS.

1 Like