Skip to content

AbstractMethodError when overriding java method with default implementation which implementation is "muted" in inherited interface #12224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
unkarjedy opened this issue Nov 10, 2020 · 4 comments
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) java interop runtime crash should not compile
Milestone

Comments

@unkarjedy
Copy link

reproduction steps

using Scala (2.13.3),

public interface BaseRootJava {
    default boolean startInWriteAction() {
        return true;
    }
}
public interface BaseIntermidiateJava extends BaseRootJava {
    String getText();

    @Override
    boolean startInWriteAction();
}
class ChildScala extends BaseIntermidiateJava {
  override def getText: String = ""
}
object Main {
  def main(args: Array[String]): Unit = {
    val action = new ChildScala
    println(action.startInWriteAction())
  }
}

problem

This code compiles but throws an error at runtime:

Exception in thread "main" java.lang.AbstractMethodError: Method MyIntentionActionScala.startInWriteAction()Z is abstract
	at MyIntentionActionScala.startInWriteAction(MyIntentionActionScala.scala)
	at Main$.main(Main.scala:5)
	at Main.main(Main.scala)

java analog will not compile

public class ChildJava implements BaseIntermidiateJava {
    @Override
    public String getText() { return null; }
}
@unkarjedy
Copy link
Author

@Jasper-M
Copy link

Is getText necessary to reproduce?

@dwijnand
Copy link
Member

I think it should "do the right thing" (return true), but if javac doesn't compile it perhaps it does so for a good reason, worth following.

@Jasper-M
Copy link

Jasper-M commented Nov 10, 2020

I think it should "do the right thing"

There doesn't seem to be agreement on what the right thing is.

Scala 2.13

scala> trait Foo { def foo = "foo" }
     | trait Bar extends Foo { override def foo: String }
     | class Baz extends Bar
trait Foo
trait Bar
class Baz

Dotty (scala/scala3#4770)

scala> trait Foo { def foo = "foo" }                                            
     | trait Bar extends Foo { override def foo: String }
     | class Baz extends Bar
3 |class Baz extends Bar
  |      ^
  |  class Baz needs to be abstract, since override def foo: => String is not defined 

I've never quite understood the reasoning behind Scala 2's behavior actually...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) java interop runtime crash should not compile
Projects
None yet
Development

No branches or pull requests

5 participants