-
Notifications
You must be signed in to change notification settings - Fork 21
Description
I've encountered an issue when upgrading the compiler to 2.12.7.
I have a piece of java code that uses the apply method of a scala case class.
final MyClass myClass = MyClass.apply(1, 2, 3L, 4)
When using MyClass
compiled with Scala 2.12.7, I get: incompatible types: java.lang.Object cannot be converted to MyClass.
Where, before it compiled fine.
I'm now looking into the generated bytecode and can see this.
Test.scala:
case class MyClass(a: Int, b: Int, c: Long, d: Int)
$ scalac Test.scala
$ scala -classpath .
Welcome to Scala 2.12.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_162).
Type in expressions for evaluation. Or try :help.
scala> :javap -p MyClass
Compiled from "Test.scala"
public class MyClass implements scala.Product,scala.Serializable {
private final int a;
private final int b;
private final long c;
private final int d;
public static java.lang.Object apply(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);
public static scala.Option<scala.Tuple4<java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object>> unapply(MyClass);
public static MyClass apply(int, int, long, int);
public static scala.Function1<scala.Tuple4<java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object>, MyClass> tupled();
public static scala.Function1<java.lang.Object, scala.Function1<java.lang.Object, scala.Function1<java.lang.Object, scala.Function1<java.lang.Object, MyClass>>>> curried();
public int a();
public int b();
public long c();
public int d();
public MyClass copy(int, int, long, int);
public int copy$default$1();
public int copy$default$2();
public long copy$default$3();
public int copy$default$4();
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public scala.collection.Iterator<java.lang.Object> productIterator();
public boolean canEqual(java.lang.Object);
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public MyClass(int, int, long, int);
}
When doing the same exercise on scala 2.12.6 I get:
$ scalac Test.scala
$ scala -classpath .
Welcome to Scala 2.12.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_162).
Type in expressions for evaluation. Or try :help.
scala> :javap -p MyClass
Compiled from "Test.scala"
public class MyClass implements scala.Product,scala.Serializable {
private final int a;
private final int b;
private final long c;
private final int d;
public static scala.Option<scala.Tuple4<java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object>> unapply(MyClass);
public static MyClass apply(int, int, long, int);
public static scala.Function1<scala.Tuple4<java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object>, MyClass> tupled();
public static scala.Function1<java.lang.Object, scala.Function1<java.lang.Object, scala.Function1<java.lang.Object, scala.Function1<java.lang.Object, MyClass>>>> curried();
public int a();
public int b();
public long c();
public int d();
public MyClass copy(int, int, long, int);
public int copy$default$1();
public int copy$default$2();
public long copy$default$3();
public int copy$default$4();
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public scala.collection.Iterator<java.lang.Object> productIterator();
public boolean canEqual(java.lang.Object);
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public MyClass(int, int, long, int);
}
A duplicate apply
method is generated in scala 2.12.7 with the following signature:
public static java.lang.Object apply(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);
and it seems this one is being picked in my Java project, causing the exception.
It seems that this is an unintended breaking change between these two versions.
Of course a workaround is using the new keyword:
final MyClass myClass = new MyClass(1, 2, 3L, 4)