NoSuchMethodError when calling java code from scala

When I execute the following code in the scala REPL console:

java.util.Collections.max(new java.util.ArrayList[String]()) 

NoSuchMethodError exception:

 java.lang.NoSuchMethodError: java.util.Collections.max(Ljava/util/Collection;)Lj ava/lang/Comparable; at .<init>(<console>:8) at .<clinit>(<console>) at .<init>(<console>:11) at .<clinit>(<console>) at $export(<console>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:592) at scala.tools.nsc.interpreter.IMain$Request$$anonfun$10.apply(IMain.sca la:828) at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:4 3) at scala.tools.nsc.io.package$$anon$2.run(package.scala:31) at java.lang.Thread.run(Thread.java:662) 

Scala 2.9.0.1, Java 1.6.0_25

Why is there an exception? The same code executed with Java behaves as expected (throws a NoSuchElementException ).

+8
scala
source share
1 answer

This is a compiler error that affects both Scala 2.8 and 2.9, where the compiler does not compute the proper trimmed method signature. I do not know the error report.

Method compilation:

 object Test { def main(a: Array[String]) { val a = new java.util.ArrayList[String]() java.util.Collections.max(a) }} 

Results in the following bytecode:

 public void main(java.lang.String[]); Code: Stack=2, Locals=3, Args_size=2 0: new #16; //class java/util/ArrayList 3: dup 4: invokespecial #18; //Method java/util/ArrayList."<init>":()V 7: astore_2 8: aload_2 9: invokestatic #24; //Method java/util/Collections.max:(Ljava/util/Collection;)Ljava/lang/Comparable; 12: pop 13: return 

Note that the bytecode in offset 9 calls the static method with the return type Comparable , while the actual Collections.max has an Object as the return type:

 $ javap -p java.util.Collections | grep max public static java.lang.Object max(java.util.Collection); 
+5
source share

All Articles