Pregunta

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

¿Fue útil?

Solución

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 = []
        }
}

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top