Reputation: 411
I'm currently working on project with both Scala and Java. And we want to rewrite some Scala code on Java. So when I've been starting rewrite my code I've faced with this issue.
CountryResponse.java:5: illegal start of type declaration
It seem like Scala couldn't compile Java's records introduced in JDK 16. I've made some research and found only this discussion on GitHub. Could someone suggest any workaround to compile Java's records?
I did try increase Scala version from 2.12.2 to 2.13.6 but problem wasn't solved.
We use Java 16, Scala 2.12.2 and Gradle 7.0.1 and also scala and java plugins for Gradle.
Also here my gradle's settings for compile both sources.
compileScala {
sourceCompatibility("16")
targetCompatibility("16")
}
sourceSets {
main {
java {
srcDirs = []
}
scala {
srcDirs = ['src/main/scala', 'src/main/java']
}
}
}
edit: update link to discussion
Upvotes: 4
Views: 1086
Reputation: 13985
I tested with following project containing both Scala and Java 16 sources. The Scala and Java source depends on each other.
If your both Java and Scala sources depend on each other, then you will need to put those sources under common folder. Lets say main/jvm
.
You can place all your Java record
s under main/java
. This will work as long as your record
s don't have dependency on Scala code. Otherwise you will have to break this into multiple modules and micromanage according to the dependency graph.
Gradle version is 7.1, and this project builds and then runs successfully (both ScalaMain and JavaMain).
build.gradle
plugins {
id 'java'
id 'scala'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
compileScala {
sourceCompatibility("16")
targetCompatibility("16")
}
sourceSets {
main {
java {
srcDirs = ['src/main/java']
}
scala {
srcDirs = ['src/main/jvm']
}
}
}
dependencies {
implementation 'org.scala-lang:scala-library:2.13.6'
}
main/java/TestJavaRecord.java
public record TestJavaRecord(int i) {}
main/jvm/TestScalaClass.scala
class TestScalaClass(val i: Int, val testJavaRecord: TestJavaRecord) {}
main/jvm/TestJavaClass.java
public class TestJavaClass {
public int i;
public TestScalaClass testScalaClass;
public TestJavaClass(int i, TestScalaClass testScalaClass) {
this.i = i;
this.testScalaClass = testScalaClass;
}
}
main/jvm/ScalaMain.scala
object ScalaMain extends App {
val testJavaRecord = new TestJavaRecord(5)
val testScalaClass = new TestScalaClass(5, testJavaRecord)
val testJavaClass = new TestJavaClass(5, testScalaClass)
println(testJavaRecord.i)
println(testScalaClass.testJavaRecord.i)
println(testJavaClass.testScalaClass.testJavaRecord.i)
}
main/jvm/JavaMain.java
public class JavaMain {
public static void main(String[] args) {
TestJavaRecord testJavaRecord = new TestJavaRecord(5);
TestScalaClass testScalaClass = new TestScalaClass(5, testJavaRecord);
TestJavaClass testJavaClass = new TestJavaClass(5, testScalaClass);
System.out.println(testJavaRecord.i());
System.out.println(testScalaClass.testJavaRecord().i());
System.out.println(testJavaClass.testScalaClass.testJavaRecord().i());
}
}
Upvotes: 4