[SI-8899] Scalatra existing builds suffer java.lang.AbstractMethodError with Scala 2.11.3 Created: 12/Oct/14  Updated: 04/Nov/14  Resolved: 04/Nov/14

Status: CLOSED
Project: Scala Programming Language
Component/s: None
Affects Version/s: Scala 2.11.3
Fix Version/s: Scala 2.11.4

Type: Bug Priority: Blocker
Reporter: Kazuhiro Sera Assignee: Lukas Rytz
Resolution: Fixed Votes: 3
Labels: None

Scala 2.11.3


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:

Comment by Jason Zaugg [ 12/Oct/14 ]

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

Comment by kenji yoshida [ 12/Oct/14 ]

more simple example


Comment by Takashi Kawachi [ 12/Oct/14 ]

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

Comment by kenji yoshida [ 12/Oct/14 ]

another examples

Comment by kenji yoshida [ 12/Oct/14 ]

also https://github.com/playframework/playframework/blob/2.3.5/framework/src/play/src/main/scala/play/api/mvc/Http.scala#L683

Comment by Grzegorz Kossakowski [ 12/Oct/14 ]

The related PR is: https://github.com/scala/scala/pull/3949

Comment by Lukas Rytz [ 12/Oct/14 ]

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.

Comment by Lukas Rytz [ 12/Oct/14 ]


Comment by Paolo G. Giarrusso [ 15/Oct/14 ]

If anybody is wondering (like me) why MIMA didn't catch it, don't worry, MIMA is fine:

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

Generated at Wed Dec 12 11:42:07 CET 2018 using JIRA 7.9.1#79001-sha1:60970b42586a2ec2760ed6cfe825b26961e62b9e.