Skip to content

VerifyError when overriding a class that overrides a vararg method and makes it final, depending on compilation order #10256

Open
@provegard

Description

@provegard

(Copied from here.)

Consider the following three Scala source files:

JSFunction.scala:

import jdk.nashorn.api.scripting.AbstractJSObject

abstract class JSFunction extends AbstractJSObject {
  final override def call(thiz: scala.Any, args: AnyRef*): AnyRef = doCall(thiz, args: _*)

  def doCall(thiz: scala.Any, args: AnyRef*): AnyRef
}

InvokableWrapper.scala:

class InvokableWrapper extends JSFunction {
  override def doCall(thiz: Any, args: AnyRef*): AnyRef = {
    println("Called with: " + args.mkString(", "))
    null
  }
}

Main.scala:

object Main extends App {
  val wrapper = new InvokableWrapper
  wrapper.call(null, "a", "b")
}

This is what I do:

> scalac *.scala
> scala Main

I get:

java.lang.VerifyError: class InvokableWrapper overrides final method call.(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:94)
        at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:90)
        at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:129)
        at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
        at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
        at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
        at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:29)
        at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:28)
        at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:61)
        at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:88)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:99)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:104)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

If I remove final in JSFunction.scala, I get the expected output:

Called with: a, b

For reference:

> scalac -version
Scala code runner version 2.12.1 -- Copyright 2002-2016, LAMP/EPFL and Lightbend, Inc.

> java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

I'm on Windows 10.

More information:

  • If I put the JSFunction and InvokableWrapper classes in the same file, I don't get the error.
  • If I compile like @lrytz did, with scalac JSFunction.scala InvokableWrapper.scala Main.scala, then it works. If I compile with scalac *.scala, it doesn't work.

In the actual code base, this error happens whenever a specific source file is changed and sbt or IDEA performs incremental compilation, so this is a real problem that cannot be fixed by compiling in a certain order. The only workaround I know of is to do a full rebuild.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions