Scala Programming Language
  1. Scala Programming Language
  2. SI-6013

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

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: Scala 2.9.1
    • Fix Version/s: Scala 2.10.0-M4, Scala 2.10.0
    • Component/s: Misc Compiler
    • Environment:

      Description

      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)
      

        Activity

        Hide
        Adriaan Moors added a comment -

        Jason, maybe you could apply some of the same sauce as with SI-4989

        Show
        Adriaan Moors added a comment - Jason, maybe you could apply some of the same sauce as with SI-4989
        Hide
        Dominik Gruntz added a comment - - edited

        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
                     ^
        
        Show
        Dominik Gruntz added a comment - - edited 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 ^
        Hide
        Jason Zaugg added a comment -

        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: https://github.com/scala/scala/commit/76c76b28f#L2R252

        Show
        Jason Zaugg added a comment - 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: https://github.com/scala/scala/commit/76c76b28f#L2R252
        Hide
        Christopher Currie added a comment -

        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.

        Show
        Christopher Currie added a comment - 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.
        Hide
        Jason Zaugg added a comment -
        Show
        Jason Zaugg added a comment - Tentative fix: https://github.com/retronym/scala/compare/ticket/6013
        Show
        Jason Zaugg added a comment - https://github.com/scala/scala/pull/820
        Hide
        Christopher Currie added a comment -

        Thanks so much for getting this fixed quickly. Is there any chance of getting a backport to a 2.9 patch release?

        Show
        Christopher Currie added a comment - Thanks so much for getting this fixed quickly. Is there any chance of getting a backport to a 2.9 patch release?
        Hide
        Jason Zaugg added a comment -

        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.

        Show
        Jason Zaugg added a comment - 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.
        Hide
        Christopher Currie added a comment -

        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.

        Show
        Christopher Currie added a comment - 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.

          People

          • Assignee:
            Jason Zaugg
            Reporter:
            Christopher Currie
          • Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development