Skip to content

Impossible cast from Long when Java varargs are involved #13645

Closed
@jlprat

Description

@jlprat

When interacting with some java code involving parametrized methods and varargs of the same type and a Scala Long is used, a ClassCastException is thrown at runtime as primitive long can't be casted to Object.

Compiler version

Scala 3.0.2 and 3.1.0-RC2

Minimized code

You can find a repo with the code here
Given this Java class

public class TypedVarargs<V> {

    public TypedVarargs<V> varArgs(V thing, V... things) {
        return this;
    }
}

And this Scala class:

object ImpossibleCast {
 
    val x = new TypedVarargs[Long]()
    val y = x.varArgs(1L)
    def main(args: Array[String]): Unit = {
        println("runs")
    }
}

Output

When running ImpossibleCast we get the following exception:

[error] java.lang.ExceptionInInitializerError
[error] 	at ImpossibleCast.main(ImpossibleCast.scala)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] 	at java.lang.reflect.Method.invoke(Method.java:498)
[error] Caused by: java.lang.ClassCastException: [J cannot be cast to [Ljava.lang.Object;
[error] 	at ImpossibleCast$.<clinit>(ImpossibleCast.scala:4)
[error] 	at ImpossibleCast.main(ImpossibleCast.scala)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] 	at java.lang.reflect.Method.invoke(Method.java:498)

Expectation

The code should work (it does under Scala 2.13.6) and print:

runs

Workaround

object ImpossibleCast {
 
    val x = new TypedVarargs[java.lang.Long]()
    val y = x.varArgs(1L)
    def main(args: Array[String]): Unit = {
        println("runs")
    }
}

Notice that if we instantiate the TypedVarargs class with java.lang.Long instead of Scala's Long the code works as expected.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions