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

Deriving from abstract Java class/method does not fail to compile #6013

Closed
scabug opened this issue Jul 2, 2012 · 10 comments
Closed

Deriving from abstract Java class/method does not fail to compile #6013

scabug opened this issue Jul 2, 2012 · 10 comments

Comments

@scabug
Copy link

scabug commented Jul 2, 2012

Given the following files:

// Base.java
public class Base {
  public boolean foo() { return true; }
}

// Abstract.java
public abstract class Abstract extends Base {
  public abstract boolean foo(); // force re-implementation in derived classes
}

// DerivedJava.java
public class DerivedJava extends Abstract {}

// DerivedScala.scala
class DerivedScala extends Abstract

// Main.scala
object Main extends App {
  new DerivedScala().foo()
}

WIth these present, javac will fail to compile DerivedJava, complaining that foo needs to be defined. However, scalac will not fail to compile DerivedScala.scala, and when Main.scala is compiled and run, it crashes with AbstractMethodError (shown here from the REPL):

scala> class Derived extends Abstract
defined class Derived

scala> new Derived().foo()
java.lang.AbstractMethodError: Derived.foo()Z
        at .<init>(<console>:9)
        at .<clinit>(<console>)
        at .<init>(<console>:11)
        at .<clinit>(<console>)
        at $print(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
        at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
        at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
        at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
        at java.lang.Thread.run(Thread.java:680)
@scabug
Copy link
Author

scabug commented Jul 2, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6013?orig=1
Reporter: Christopher Currie (codemonkey)
Affected Versions: 2.9.1
Other Milestones: 2.10.0

@scabug
Copy link
Author

scabug commented Jul 3, 2012

@adriaanm said:
Jason, maybe you could apply some of the same sauce as with #4989

@scabug
Copy link
Author

scabug commented Jul 3, 2012

@dgruntz said (edited on Jul 3, 2012 9:33:25 PM UTC):
Class DerivedScala extends the abstract class Abstract. I expected that the compiler flags an error on class DerivedScala, as its base class contains a deferred definition of a method, similarly to

scala> class A {def foo = 0 }
defined class A

scala> abstract class B extends A { def foo: Int }
defined class B

scala> class C extends B
<console>:9: error: class C needs to be abstract, since there is a deferred decl
aration of method foo in class B of type => Int which is not implemented in a su
bclass
       class C extends B
             ^

@scabug
Copy link
Author

scabug commented Jul 3, 2012

@retronym said:
The check that should fire here ("there is a deferred declaration of ... which is not implemented in a subclass") is disabled by a condition added in: scala/scala@76c76b28f#L2R252

@scabug
Copy link
Author

scabug commented Jul 3, 2012

Christopher Currie (codemonkey) said:
Dominik,

I understand that in order to compile successfully that DerivedJava must be declared abstract. The DerivedJava class is there to demonstrate an expected compilation failure. The description doesn't make sense if DeclaredJava compiles, so I have returned the description to its original state. The class is not "used" except as an example of where javac should (and does) fail to compile.

The compiler does not flag an error on DerivedScala, which is the point of the bug report.

@scabug
Copy link
Author

scabug commented Jul 3, 2012

@scabug
Copy link
Author

scabug commented Jul 4, 2012

@retronym said:
scala/scala#820

@scabug scabug closed this as completed Jul 4, 2012
@scabug
Copy link
Author

scabug commented Jul 4, 2012

Christopher Currie (codemonkey) said:
Thanks so much for getting this fixed quickly. Is there any chance of getting a backport to a 2.9 patch release?

@scabug
Copy link
Author

scabug commented Jul 5, 2012

@retronym said:
May I ask why? This seems a pretty obscure bug that wouldn't really be a blocker.

The policy, given limited resources, is to only backport if the interested party either:

  1. does the leg-work to cherry-pick the commit to the 2.9.x branch and checks that the test suite passes, and submits a pull request, or
  2. has a support contract with TypeSafe.

It's also not clear if there will be a 2.9.3 release at all.

@scabug
Copy link
Author

scabug commented Jul 5, 2012

Christopher Currie (codemonkey) said:
No, it's not a blocker, though it is a bug generator, as a Java dependency of a Scala project I maintain added a new abstract method in a version upgrade; not having the compiler fail created a latent bug at runtime.

I understand there may not be a 2.9.3, but if there is I would predict it will before 2.10, and have less impact to development (and more importantly, my end users) than a 2.10 upgrade.

I'll take a look at doing the cherry-pick legwork, in the hopes that a 2.9.3 release happens. Thanks again for the quick fix.

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

2 participants