Question

The default scala plugin task flow compiles Java before Scala so importing Scala sources within Java causes "error: cannot find symbol". scala task flow

Was it helpful?

Solution

Java and Scala can be combined in the scala sources to have them compiled jointly, e.g.

sourceSets {
    main {
        scala {
            srcDirs = ['src/main/scala', 'src/main/java']
        }
        java {
            srcDirs = []
        }
}

OTHER TIPS

If your java code use some external libraries like Lombok, using scala compiler to build java class will failed, as scala compiler don't know annotations.

My solution is to change the task dependencies, make compiling Scala before Java.

tasks.compileJava.dependsOn compileScala
tasks.compileScala.dependsOn.remove("compileJava")

Now the task compileScala runs before compileJava, that's it.

If your java code depends on scala code, you need to do two more steps,

  1. Separate the output folder of scala and java,

    sourceSets {
        main {
            scala {
                outputDir = file("$buildDir/classes/scala/main")
            }
            java {
                outputDir = file("$buildDir/classes/java/main")
            }
        }
    
  2. Add the scala output as a dependency for compileJava,

    dependencies {
        compile files("$sourceSets.main.scala.outputDir")
    }
    

for gradle kotlin dsl you can use this piece

 sourceSets {

    main {
        withConvention(ScalaSourceSet::class) {
            scala {
                setSrcDirs(listOf("src/main/scala", "src/main/java"))
            }
        }
        java {
            setSrcDirs(emptyList<String>())
        }
    }
    test {
        withConvention(ScalaSourceSet::class) {
            scala {
                setSrcDirs(listOf("src/test/scala", "src/test/java"))
            }
        }
        java {
            setSrcDirs(emptyList<String>())
        }
    }
}

Posting this update from the future here, as it would saved me a day.

gradle 6 doesn't support task dependencies modification, but here is what you can do:

// to compile Java after Scala
tasks.compileScala.classpath = sourceSets.main.compileClasspath
tasks.compileJava.classpath += files(sourceSets.main.scala.classesDirectory)

And here is documentation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top