Abstract methods and the varargs annotation
java, scala, scala-java-interop, variadic-functions
Solution
I don't know `Scala`, but in Java varargs is just an array.
So in Java it will work this way, with one warning:
package tests.StackOverflow.q27052394;
import java.util.Arrays;
public class Runner {
public interface Bar {
public abstract void bar(java.lang.String ... ss);
}
public static class Baz implements Bar {
public void bar(java.lang.String[] array) {
System.out.println(Arrays.toString(array));
}
}
public static void main(String[] args) {
Bar b = new Baz();
b.bar("hello", "world");
}
}
May be if you can fool `Scala` the same way, you will overcome the bug.
Problem
Scala provides a `@varargs` annotation that generates a Java varargs forwarder method, which makes it possible to write something like this: ``` import scala.annotation.varargs class Foo { @varargs def foo(args: String*): Unit = { args.foreach(println) } } ``` And then to call this method from Java without needing to create a `scala.Seq`: ``` Foo foo = new Foo(); foo.foo("a", "b"); ``` Which is pretty nice. Unfortunately the forwarding part doesn't seem to happen when the method is abstract: ``` trait Bar { @varargs def bar(args: String*): Unit } class Baz extends Bar { def bar(args: String*): Unit = { args.foreach(println) } } ``` Now if we have this Java code: ``` Bar bar = new Baz(); bar.bar("a", "b"); ``` We get this exception (at runtime): ``` java.lang.AbstractMethodError: Baz.bar([Ljava/lang/String;)V ``` We can confirm the problem with `javap`: ``` public interface Bar { public abstract void bar(java.lang.String...); public abstract void bar(scala.collection.Seq<java.lang.String>); } public class Baz implements Bar { public void bar(scala.collection.Seq<java.lang.String>); public Baz(); } ``` So nope, the forwarder definitely isn't getting implemented. Putting the annotation on both `bar` methods fails to compile: ``` A method with a varargs annotation produces a forwarder method with the same signature (args: Array[String])Unit as an existing method. ``` And of course putting the annotation only on the `bar` in `Baz` means we can't use the forwarder from a `Bar` instance. This seems like it must be a bug, but it also seems extremely easy to run into, and I'm not seeing anything in the issue tracker. Am I using `@varargs` correctly? If so, is there a workaround that would make it do what you'd expect here?