How to support multiple projects in multiple languages (Java and Scala) in Gradle?

build, gradle, java, scala

Solution

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.

Problem

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?

Original source