Skip to content
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

Scala trait / abstract class and Java abstract class interaction compiles but throws AbstractMethodError at runtime #10534

Closed
mrerrormessage opened this issue Sep 29, 2017 · 2 comments

Comments

@mrerrormessage
Copy link

mrerrormessage commented Sep 29, 2017

I'm running into an error where I have a Java abstract class extending a Scala abstract class, then I'm anonymously instantiating the Java abstract class in Scala without implementing a member. Rather than receive a compiler message about unimplemented abstract methods, the program compiles and then errors at runtime.

The code here can be downloaded in this gist

I have in scala:

abstract class AbstractFoo {
  def bar: String
}

and in java:

abstract class Foo extends AbstractFoo {
  String bar = "abc";

  public String baz() {
    return bar();
  }
}

And then back in scala:

object Main extends App {
  val f = new Foo() { }
  println(f.baz)
}

Compiles without error, then when running, I see:

[error] java.lang.AbstractMethodError: bug.Foo.bar()Ljava/lang/String;
[error]   at bug.Foo.baz(Foo.java:7)
[error]   at bug.Main$.delayedEndpoint$bug$Main$1(Main.scala:5)
[error]   at bug.Main$delayedInit$body.apply(Main.scala:3)

A few notes on how the problem changes when the code is altered:

  1. Changing AbstractFoo to a trait gives the same result as when it is an abstract class (of course, the java code needs to switch in implements for extends as well).
  2. Renaming the java field bar to _bar causes the error message that I would hope and expect to see:
.../src/main/scala/Main.scala:4:15: object creation impossible, since method bar in class AbstractFoo of type => String is not defined
  1. Making the java field bar private also causes the same compiler error message.
  2. Changing Main to call foo.bar instead of foo.baz causes the program to compile and run, printing "abc". I'm not certain whether this behavior is expected. It means that java fields named the same as scala methods receive precedence over the scala methods.
  3. Changing the assignment in main to val f: AbstractFoo = new Foo() { } and the statement to println(f.bar) also compiles without error and causes an AbstractMethodError at runtime.

Environment information:

  • Tested under JDK 8u141 and JDK 9
  • Tested using sbt and scala versions 2.12.2 and 2.12.3
@mrerrormessage mrerrormessage changed the title Scala abstract class / Java abstract class interaction compiles but throws AbstractMethodError at runtime Scala trait / abstract class and Java abstract class interaction compiles but throws AbstractMethodError at runtime Sep 29, 2017
@lrytz
Copy link
Member

lrytz commented Sep 8, 2021

This (and the mentioned variants) no longer compiles, I believe it was fixed by scala/scala#9525.

Test.scala:6: error: weaker access privileges in overriding
def bar: String (defined in class AbstractFoo)
  override should be public
  val f = new Foo() { }
              ^
1 error

Would be worth adding a unit test.

@lrytz lrytz closed this as completed Sep 8, 2021
@SethTisue
Copy link
Member

SethTisue commented Sep 9, 2021

Is there a volunteer out there to add a test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants