10

Let's say I have the following class hierarchy:

interface Collection<E>
{
    Collection<E> $plus(E element)
}

interface MutableCollection<E> extends Collection<E>
{
    @Override
    MutableCollection<E> $plus(E element)
}

interface Set<E> extends Collection<E>
{
    @Override
    Set<E> $plus(E element)
}

interface MutableSet<E> extends Set<E>, MutableCollection<E>
{
    @Override
    default MutableSet<E> $plus(E element)
    {
        // ... implementation
    }
}

abstract class AbstractArraySet<E> implements Set<E>
{
    // ... no $plus(...) implementation
}

class ArraySet<E> extends AbstractArraySet<E> implements MutableSet<E>
{
    // ... no $plus(...) implementation
}

As you can see, only the MutableSet class provides an implementation for the $plus method. In a Test case, I am calling this method on an instance of type ArraySet. The Test always passes in the CI environment, while it always fails with an AbstractMethodError on my local environment. In both cases, I am using Gradle (2.7).


The Error:

java.lang.AbstractMethodError: Method dyvil/collection/mutable/ArraySet.$plus(Ljava/lang/Object;)Ldyvil/collection/Collection; is abstract

    at dyvil.collection.mutable.ArraySet.$plus(ArraySet.java)
    at dyvil.tests.CollectionTests.testCollection(CollectionTests.java:99)
    at ...

Test Code:

testCollection(new ArraySet());

public void testCollection(Collection collection)
{
    assertEquals(mutable.$plus("newElement"), collection.$plus("newElement"));
}

java -version output:

  • CI (where it works):

    java version "1.8.0"
    Java(TM) SE Runtime Environment (build 1.8.0-b132)
    Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
    
  • Local (where it fails):

    java version "1.8.0_71"
    Java(TM) SE Runtime Environment (build 1.8.0_71-b15)
    Java HotSpot(TM) 64-Bit Server VM (build 25.71-b15, mixed mode)
    

I am expecting this to be some sort of javac bug, where the compiler fails to add all required bridge methods (the code compiles without any warnings or errors). In IntelliJ IDEA, the problem occurs both using javac and the Eclipse Compiler.

Clashsoft
  • 11,553
  • 5
  • 40
  • 79
  • Are you presenting what you already proved to be the minimal setup to reproduce the error? There are a lot of interfaces here, if it can't be demostrated with fewer then the problem looks quite complex. – Marko Topolnik Jan 31 '16 at 15:11
  • Decompile the `MutableSet.class` that is executed in runtime in your local environment. Is there a default method there? – Dragan Bozanovic Jan 31 '16 at 15:12
  • @DraganBozanovic, yes, there are bridge methods for all super-interface `$plus` methods. There are no bridge methods in the `ArraySet` class, though. – Clashsoft Jan 31 '16 at 15:14
  • No repro on "Netbeans with jdk1.8.0_65" – Ferrybig Jan 31 '16 at 15:15
  • What is your project structure? Is the code in which you do assertions in the same jar as `MutableSet`? – Dragan Bozanovic Jan 31 '16 at 15:25
  • I'd suggest reproducing without the dollar sign in the method name. – Marko Topolnik Jan 31 '16 at 15:59
  • @DraganBozanovic check the Test Code link - it's all in the same project. – Clashsoft Jan 31 '16 at 16:56
  • @MarkoTopolnik the problem also occurs for methods with normal named like `mapped`, so this can't be the problem. – Clashsoft Jan 31 '16 at 17:12
  • And does it occur in any setting simpler than yours? If this is a compiler bug, it will be crucial to exactly delineate the circumstances where it occurs. – Marko Topolnik Jan 31 '16 at 17:15
  • I can't test it right now, but I guess you could remove the `Collection` layer. I am not sure though, since that is what the error talks about. Will test as soon as I have access to my dev environment. – Clashsoft Jan 31 '16 at 17:31
  • Ok, did you decompile the `.class` file or you just assumed that default method is there because you see it in the source (`.java`) file? – Dragan Bozanovic Jan 31 '16 at 17:39
  • @DraganBozanovic I checked it with `javap` – Clashsoft Jan 31 '16 at 17:40
  • Locally, the problem manifests from IDEA only, or can you reproduce with plain `javac` on command line? (I realize you can't answer this at the moment) – Marko Topolnik Jan 31 '16 at 18:51
  • I set it up in IDEA, with JDK 1.8.0_71, and couldn't reproduce. – Marko Topolnik Jan 31 '16 at 18:58
  • @MarkoTopolnik I haven't tested it with javac, but I can reproduce it with Gradle on my local env. At the very least, you should be able to reproduce this problem by cloning the [repo](https://github.com/Dyvil/Dyvil) and running `gradle build test`. – Clashsoft Feb 01 '16 at 09:00
  • Did it: `BUILD SUCCESSFUL` – Marko Topolnik Feb 01 '16 at 09:57
  • Turns out doing a full `clean` and rebuild fixed the problem for me as well. Nevertheless, there must have been a bug involved at some point that caused the faulty binaries. Thanks for you efforts, anyway. – Clashsoft Feb 03 '16 at 18:40

1 Answers1

0

(Answer is made based on author's comment above: problem was solved):

Doing a full clean and rebuild fixed the problem as well.

Nevertheless, there must have been a bug involved at some point that caused the faulty binaries.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241