6

I am trying to convert our antiquated Ant build to Gradle. The project contains about Java 50 sub-projects and 10 Scala sub-projects. The Java projects only contain Java and the Scala projects only Scala. Each project is getting built by Java then Scala which is slowing down our build considerably.

I want to place as much common logic in the root build.gradle file as possible which looks like this:

subprojects {
    apply plugin: 'java'
    apply plugin: 'scala'

    sourceCompatibility=1.7
    targetCompatibility=1.7

    sourceSets {
        main {
            scala {
                srcDir 'src'
            }
            java {
                srcDir 'src'
            }
        }
        test {
            scala {
                srcDir 'test'
            }
            java {
                srcDir 'test'
            }
        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        scalaTools "org.scala-lang:scala-compiler:2.9.3"
        compile "org.scala-lang:scala-library:2.9.3"
    }

    // Use the sbt compiler (not scalac ant task)
    tasks.withType(ScalaCompile) {
        scalaCompileOptions.useAnt = false
    }

    task showCompileClasspath << {
       sourceSets.main.compileClasspath.each { println it }
    }

    test {
        systemProperty "user.dir", projectDir
    }
}

When I run my build I get the following output, notice that :esb-server:compileJava and :esb-server:compileScala contain the same warnings, so the classes are being built twice. Also notice that every other project contains a compileJava and compileScala

:common:assemble
:esb-server:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:esb-server:compileScala
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:esb-server:processResources UP-TO-DATE
:esb-server:classes
:esb-server:jar
:esb-server:assemble
:plugins:compileJava UP-TO-DATE
:plugins:compileScala UP-TO-DATE
:plugins:processResources UP-TO-DATE
:plugins:classes UP-TO-DATE
:plugins:jar
:plugins:assemble
:raas-transform:assemble
:saxonee-helper:assemble
:scala-common:compileJava UP-TO-DATE
:scala-common:compileScala
/Users/iain.hull/code/trunk/ccdev/scala-common/src/com/workday/esb/assembly/audit/TreeAudit.scala:138: method first in trait IterableLike is deprecated: use `head' instead
    override def getLast():Option[AuditNode] = if (children.isEmpty) None else children.first.getLast
                                                                                        ^
one warning found
:scala-common:processResources UP-TO-DATE
:scala-common:classess
:scala-common:jar
:scala-common:assemble
:plugins:hibernatepersistence:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:plugins:hibernatepersistence:compileScala
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:plugins:hibernatepersistence:processResources
:plugins:hibernatepersistence:classes
:plugins:hibernatepersistence:jar
:plugins:hibernatepersistence:assemble

I know that the two apply plugin lines at the top of my root build.gradle are causing this behaviour. However if I only apply the correct plugin to each subproject I cannot refactor the common configuration into my root build.gradle. Another approach would be to just use the Scala plugin for everything, but is this the best way?

Can I use the Java plugin to compile Java projects and the Scala plugin to compile Scala projects, and still refactor common build configuration across all my projects to the root build.gradle? What is the best way to support multiple languages like this in Gradle?

2
  • As Gradle document on scala plugin says - The Scala plugin extends the Java plugin to add support for Scala projects. And compileScala actually dependsOn compileJava that's why you see them both executing for each project Commented Apr 5, 2013 at 8:11
  • Thanks for your input, but yes I know this. However what is the best way to support projects with both java and scala? Is it to just treat everything as scala, since it includes java? What happens if we decided to add a groovy project in the future? Would it have to have the scala and groovy nature? Should I standardise my sourceset structure before worrying about this? Commented Apr 5, 2013 at 18:28

1 Answer 1

6

How about something like this:

configure(subprojects.findAll {project  ->
    file('src/main/java').exists()
}) {
    apply plugin: 'java'
}

configure(subprojects.findAll {project  ->
    file('src/main/scala').exists()
}) {
    apply plugin: 'scala'
}

Because your source directory is src, some other discriminator mechanism inside the closures is needed.

Sign up to request clarification or add additional context in comments.

4 Comments

This won't work, look carefully at his sourcesets definition. There's no src/main/java or src/main/scala, only src.
True, that's why I've mentioned or use any other discriminator inside the closures. It just servers as example of conditionally applying plugin. Thanks
Thanks for your answer, I wasn't aware of the configure function, I might be able to use it slightly differently. Place the apply plugin statements in the respective sub-projects then use configure to find the sub-projects with a java nature and configure these and likewise for the scala projects. Although I am worries about the order of execution.
I would dearly love to use the default maven/gradle sourcesets. This is something i plan to look at once I get gradle up and running. At the moment I have to maintain the ant build, and do not want to implement this kind of change there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.