10 x apply plugin: $x works but list.each { apply plugin: it } doesn't ?!


(Moritz) #1

Hey,

I just ran into a problem that I don’t really understand. We do have a multi project build (main project: oscs, subprojects: dwh, web) and the main build file is applying a bunch of different plugins with a lot of “apply plugin”-statements in the allprojects closure:

apply plugin: 'base'
    apply plugin: 'maven'
    apply plugin: 'java'
    apply plugin: 'war'
    apply plugin: 'tomcat'
    apply plugin: 'idea'
    apply plugin: 'eclipse'

As this looked a little messy to me, I changed it into

['base', 'maven', 'java', 'war', 'tomcat', 'idea', 'eclipse'].each {
        apply plugin: it
    }

From my point of view, both solutions should be equivalent but the latter produces an error:

FAILURE: Build failed with an exception.
  * Where:
Build file '/Users/moritzprinz/Documents/git/oscs/build.gradle' line: 40
  * What went wrong:
A problem occurred evaluating root project 'oscs'.
> Could not find property 'compile' on configuration container.
  * Try:
Run with --info or --debug option to get more log output.

The whole allprojects closure looks like this:

allprojects {
    group = projectGroup
    version = projectVersion
      sourceCompatibility = 1.6
    targetCompatibility = 1.6
      apply plugin: 'base'
    apply plugin: 'maven'
    apply plugin: 'java'
    apply plugin: 'war'
    apply plugin: 'tomcat'
    apply plugin: 'idea'
    apply plugin: 'eclipse'
          repositories {
        maven {
            name 'nexus'
            url "http://some/nexus"
        }
    }
      configurations.compile.transitive = true
      archivesBaseName = project.projectName
      [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
      dependencies {
        tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
               "org.apache.tomcat.embed:tomcat-embed-logging-log4j:${tomcatVersion}"
        tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
            exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
        }
    }
      // some Java classes inside the project actually depend on the buildDir being 'target'. Watch out!
    buildDir = 'target'
      sourceSets {
        main.output.resourcesDir = sourceSets.main.output.classesDir
        test.output.resourcesDir = sourceSets.test.output.classesDir
    }
}

Why does this happen?

Cheers,

Moritz


(Luke Daley) #2

Check that you aren’t introducing another change, as I can’t reproduce this. I took your code, made some adjustments for missing variables (e.g. 'projectVersion), ran it both ways and got the same result. I ran it with Gradle 1.0.


(Moritz) #3

You’re right. If I’m not including the sub projects in the settings.gradle, it gives the same result. As soon as I include them it breaks. Looks like there’s something wrong with the subproject configuration.


(Moritz) #4

Okay, looks like I finally found the problem. By using

['base', 'maven', 'java', 'war', 'tomcat', 'idea', 'eclipse'].each {
        apply plugin: plugin
    }

in the main build file, the settings are just applied on the main project (allprojects closure!) and not on the subprojects. Instead using

['base', 'maven', 'java', 'war', 'tomcat', 'idea', 'eclipse'].each { plugin ->
        it.apply plugin: plugin
    }

works for me.


(Luke Daley) #5

Glad you got it working.

That actually makes sense if you understand how Groovy resolves symbols in closures. I’ll think on if we can ease this awkwardness for Gradle users.