Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-8899

Scalatra existing builds suffer java.lang.AbstractMethodError with Scala 2.11.3

    Details

    • Type: Bug
    • Status: CLOSED
    • Priority: Blocker
    • Resolution: Fixed
    • Affects Version/s: Scala 2.11.3
    • Fix Version/s: Scala 2.11.4
    • Component/s: None
    • Labels:
      None
    • Environment:

      Scala 2.11.3

      Description

      Scalatra 2.3.0 works fine on Scala 2.11.0 , 2.11.1 and 2.11.2. However, it suffers java.lang.AbstractMethodError with Scala 2.11.3.

      2014-10-12 12:30:50,627 ERROR [qtp1562951302-64] controller.Controllers$members$ org.scalatra.ScalatraParams.filterImpl(Lscala/Function1;Z)Ljava/lang/Object;
      java.lang.AbstractMethodError: org.scalatra.ScalatraParams.filterImpl(Lscala/Function1;Z)Ljava/lang/Object;
          at scala.collection.TraversableLike$class.filter(TraversableLike.scala:270) ~[scala-library-2.11.3.jar:na]
          at org.scalatra.ScalatraParams.filter(ScalatraContext.scala:9) ~[scalatra_2.11-2.3.0.jar:2.3.0]
          at skinny.StrongParameters.permit(StrongParameters.scala:18) ~[skinny-common_2.11-1.3.3.jar:1.3.3]
          at skinny.controller.Params.permit(Params.scala:46) ~[skinny-framework_2.11-1.3.3.jar:1.3.3]
          at skinny.controller.SkinnyResourceActions$$anonfun$createResource$1.apply(SkinnyResourceActions.scala:139) ~[skinny-framework_2.11-1.3.3.jar:1.3.3]
          at skinny.controller.SkinnyControllerBase$class.withFormat(SkinnyControllerBase.scala:108) ~[skinny-framework_2.11-1.3.3.jar:1.3.3]
          at skinny.controller.SkinnyController.withFormat(SkinnyController.scala:6) [skinny-framework_2.11-1.3.3.jar:1.3.3]
          at skinny.controller.SkinnyResourceActions$class.createResource(SkinnyResourceActions.scala:135) ~[skinny-framework_2.11-1.3.3.jar:1.3.3]
          at controller.MembersController.createResource(MembersController.scala:8) ~[classes/:na]
      

      I just tried Scalatra builds with the 2.11.3 compiler. They works fine.

      See also for details:
      https://github.com/skinny-framework/skinny-framework/issues/193

        Attachments

          Activity

          Hide
          retronym Jason Zaugg added a comment -

          Lukas, looks like this stems from 9276a1205f74fdec74206209712831913e93f359. Did we reason incorrectly about the binary compatibilty of that change?

          Show
          retronym Jason Zaugg added a comment - Lukas, looks like this stems from 9276a1205f74fdec74206209712831913e93f359. Did we reason incorrectly about the binary compatibilty of that change?
          Hide
          kenji yoshida kenji yoshida added a comment -
          Show
          kenji yoshida kenji yoshida added a comment - more simple example https://github.com/xuwei-k/SI-8899
          Hide
          tkawachi Takashi Kawachi added a comment -

          As kenji shown in the sample code, it's not specific to Scalatra. It seems to be caused when it extends standard collection.

          Show
          tkawachi Takashi Kawachi added a comment - As kenji shown in the sample code, it's not specific to Scalatra. It seems to be caused when it extends standard collection.
          Show
          kenji yoshida kenji yoshida added a comment - - edited another examples https://gist.github.com/xuwei-k/5028ccf9a4d4af890d0f https://gist.github.com/xuwei-k/aa558ab4b5729394a33b
          Show
          kenji yoshida kenji yoshida added a comment - also https://github.com/playframework/playframework/blob/2.3.5/framework/src/play/src/main/scala/play/api/mvc/Http.scala#L683
          Hide
          grek Grzegorz Kossakowski added a comment -
          Show
          grek Grzegorz Kossakowski added a comment - The related PR is: https://github.com/scala/scala/pull/3949
          Hide
          rytz Lukas Rytz added a comment - - edited

          Making filterImpl non-private in PR #3949 was indeed not binary compatible. The problem is that making a trait method non-private changes its calling convention. Here's an example:

          trait Tl {
            private def f1Impl = 0
            def f1 = f1Impl
           
            private[p] def f2Impl = 0
            def f2 = f2Impl
          }
           
          class Mp extends Tl
          

          The point is that the invocation of f1Impl is statically known. So the compiler optimizes it and directly invokes the static method f1Impl in the trait implementation class Tl$class.

          Method f2Impl on the other hand may be overwritten in subclasses of Tl, therefore the invocation is compiled as an invoke-interface of the method f2Impl in interface Tl. In the subclass Mp, a mixin is generated for f2Impl.

           
          public abstract interface p/Tl {
            // NOTE: f1Impl is missing - it's private!
            public abstract f1()I
            public abstract f2Impl()I
            public abstract f2()I
          }
           
          public abstract class p/Tl$class {
            private static f1Impl(Lp/Tl;)I
            public static f1(Lp/Tl;)I
              ALOAD 0
              INVOKESTATIC p/Tl$class.f1Impl (Lp/Tl;)I  // Directly invokes the static method
           
            public static f2Impl(Lp/Tl;)I
            public static f2(Lp/Tl;)I
              ALOAD 0
              INVOKEINTERFACE p/Tl.f2Impl ()I  // Interface method
          }
           
          public class p/Mp implements p/Tl  {
            // generated mixins (forward to the static functions in Tl$class)
            public f1()I
            public f2Impl()I
            public f2()I
          }
          

          The manifestation: subclasses of TraversableLike compiled with 2.11.2 don't have a mixin for filterImpl, but the standard library of 2.11.3 invokes the interface method.

          Show
          rytz Lukas Rytz added a comment - - edited Making filterImpl non-private in PR #3949 was indeed not binary compatible. The problem is that making a trait method non-private changes its calling convention. Here's an example: trait Tl { private def f1Impl = 0 def f1 = f1Impl   private[p] def f2Impl = 0 def f2 = f2Impl }   class Mp extends Tl The point is that the invocation of f1Impl is statically known. So the compiler optimizes it and directly invokes the static method f1Impl in the trait implementation class Tl$class . Method f2Impl on the other hand may be overwritten in subclasses of Tl , therefore the invocation is compiled as an invoke-interface of the method f2Impl in interface Tl . In the subclass Mp , a mixin is generated for f2Impl .   public abstract interface p/Tl { // NOTE: f1Impl is missing - it's private! public abstract f1()I public abstract f2Impl()I public abstract f2()I }   public abstract class p/Tl$class { private static f1Impl(Lp/Tl;)I public static f1(Lp/Tl;)I ALOAD 0 INVOKESTATIC p/Tl$class.f1Impl (Lp/Tl;)I // Directly invokes the static method   public static f2Impl(Lp/Tl;)I public static f2(Lp/Tl;)I ALOAD 0 INVOKEINTERFACE p/Tl.f2Impl ()I // Interface method }   public class p/Mp implements p/Tl { // generated mixins (forward to the static functions in Tl$class) public f1()I public f2Impl()I public f2()I } The manifestation: subclasses of TraversableLike compiled with 2.11.2 don't have a mixin for filterImpl , but the standard library of 2.11.3 invokes the interface method.
          Show
          rytz Lukas Rytz added a comment - https://github.com/scala/scala/pull/4048
          Hide
          pggiarrusso Paolo G. Giarrusso added a comment -

          If anybody is wondering (like me) why MIMA didn't catch it, don't worry, MIMA is fine:
          https://github.com/lrytz/scala/commit/9276a1205f74fdec74206209712831913e93f359

          The corresponding mima-failures can be whitelisted, as the changes are only to private[scala].

          Show
          pggiarrusso Paolo G. Giarrusso added a comment - If anybody is wondering (like me) why MIMA didn't catch it, don't worry, MIMA is fine: https://github.com/lrytz/scala/commit/9276a1205f74fdec74206209712831913e93f359 The corresponding mima-failures can be whitelisted, as the changes are only to private[scala].

            People

            • Assignee:
              rytz Lukas Rytz
              Reporter:
              seratch Kazuhiro Sera
            • Votes:
              3 Vote for this issue
              Watchers:
              10 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: