JavaPlugin vs JavaBasePlugin

Hi!
I’m working on a multi-project build and we’re currently migrating from gradle 6 to 7.6.1 .
Previously all the subprojects with java code had apply plugin: 'java', now most are apply plugin: 'java-library', with some still having apply plugin: 'java' (those that are not libaries).

There are a bunch of configs, that are blanket-applied to all subprojects, with an additional check if it’s a java project or not, e.g.:

plugins.withType(JavaPlugin).all {
    logger.debug "Configuring default values for plugin 'JavaPlugin' in $project"

    // all java projects should have code analysis
    project.apply plugin: 'com.github.spotbugs'
    project.apply plugin: 'pmd'
    project.apply plugin: 'jacoco'
}

Now my question is: I noticed that JavaBasePlugin exists and now I’m unsure on what to use where or if I can just leave those configs as-is (I know, I can switch to configureEach etcpp, but for now I just want to know about JavaBasePlugin).

According to the Gradle source, JavaBasePlugin and JavaPlugin seem to be unrelated to each other(in terms of the java class hierarchy) but the javadoc seems to be pretty much the same (gradle/JavaPlugin.java at master · gradle/gradle · GitHub vs gradle/JavaBasePlugin.java at master · gradle/gradle · GitHub). What is the difference? What should I use?

They are unrelated in terms of class hierarchy, but the java plugin applies the java-base plugin: https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/java/org/gradle/api/plugins/JavaPlugin.java#L247

Basically it is a semantical / architectural separation as far as I remember.
The java-base plugin brings in all the types like tasks and so on.
And the java plugin then on top brings in some opinion / conventions, like also applying the jvm-test-suite plugin, defining the Java component, defining the default test suite, and so on.

In practice, you seldomly want to actually apply the java-base plugin manually.

Also the java-library plugin automatically applies the java plugin and just adds some more opinion on top, like the api configurations and so on.

I know, I can switch to configureEach

Actually, you should neither use .all, nor .configureEach, or plugins. at all. :smiley:
If you look at the getPlugins() JavaDoc it tells you not to use it but alternatives like pluginManager.withPlugin('java') { ... }. But you even shouldn’t use that and the legacy apply but instead do it the other way around, define a convention plugin that applies the java plugin and those other plugins and then apply that convention plugin in your actual build scripts. :wink: