NoSuchMethodError при вызове Java-кода из Scala - PullRequest
8 голосов
/ 29 мая 2011

Когда я выполняю следующий код в консоли scala REPL:

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

NoSuchMethodError возникает исключение:

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

Почему здесь выдается исключение?Тот же код, выполняемый из Java, ведет себя как ожидалось (throws NoSuchElementException).

1 Ответ

5 голосов
/ 29 мая 2011

Это ошибка компилятора, которая затрагивает как Scala 2.8, так и 2.9, когда компилятор не вычисляет правильную стертую сигнатуру метода.Я не знаю об отчете об ошибке.

Компиляция метода:

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

Результат в следующий байт-код:

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

Обратите внимание, что байт-код со смещением 9вызывает статический метод с типом возврата Comparable, тогда как фактический Collections.max имеет Object в качестве типа возврата:

$ javap -p java.util.Collections | grep max
    public static java.lang.Object max(java.util.Collection);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...