Strange default method behavior with different Java versions
Suppose 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 called this method on an instance of type arrayset The test is always passed in the CI environment, while the abstractmethoderror error error always occurs in the local environment In both cases, I use gradle (2.7)
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 do you work):
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 failed):
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 expect this to be a javac error, and the compiler cannot add all the necessary bridging methods (the code is compiled without any warnings or errors) In IntelliJ idea, the problem is using javac and eclipse compiler
Solution
(the answer is based on the author's comments: the problem is solved):
Doing a complete cleaning and reconstruction also solves the problem
However, to some extent, it is bound to cause wrong binary files