How do I detect if a sub project has applied a given plugin (e.g. jar or war)

I have a root project with 2 sub projects,

.
├── build.gradle
├── settings.gradle
└── jar
    ├── build.gradle
└── war
    ├── build.gradle

jar/build.gradle

apply plugin: 'java'

war/build.gradle

apply plugin: 'war'

I’m trying to detect whether a given plugin is present in a project and take different actions from the root/build.gradle:

build.gradle

//subprojects {
//
  if (it.plugins.withType(org.gradle.api.plugins.WarPlugin)) {
//
      println "Project $it.name: WAR == ${it.plugins.withType(org.gradle.api.plugins.WarPlugin).size() > 0}"
//
  }
//
  if (it.plugins.withType(org.gradle.api.plugins.JavaPlugin)) {
//
      println "Project $it.name: JAR == ${it.plugins.withType(org.gradle.api.plugins.JavaPlugin).size() > 0}"
//
  }
//}
  subprojects {
    if (it.plugins.hasPlugin('war')) {
        println "Project $it.name: WAR == ${it.plugins.withType(org.gradle.api.plugins.WarPlugin).size() > 0}"
    }
    if (it.plugins.hasPlugin('java')) {
        println "Project $it.name: JAR == ${it.plugins.withType(org.gradle.api.plugins.JavaPlugin).size() > 0}"
    }
}

With the respective plugin applied in the sub project build.gradle, the plugins are not reported as applied. However once I move the apply plugin statement to the root project it works:

project (':war') {
    apply plugin: 'war'
}

What needs to be done to make the plugins reported properly and still have the apply plugin within the sub project? I don’t want to move that to the root as I want to keep the sub projects as portable as possible.

The root project’s build script gets evaluated before the build scripts for subprojects. One way out is to resort to callbacks:

subprojects {
    plugins.withType(JavaPlugin) {
        ...
    }
    plugins.withType(WarPlugin) {
        ...
    }
}

An alternative is to have your own script plugins that subprojects apply as needed (e.g. ‘apply from: “$rootDir/gradle/java.gradle”’).

1 Like

Thanks, I understand that with the callback I will receive a call when a plugin has been added. Just implemented it and works perfectly.