10

Lassen Sie uns sagen, dass ich die folgende Klassenhierarchie:Seltsam Standardmethode Verhalten mit verschiedenen Java-Versionen

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 
} 

Wie Sie sehen können, nur die MutableSet-Klasse stellt eine Implementierung für die $plus Methode. In einem Testfall rufe ich diese Methode für eine Instanz des Typs ArraySet auf. Der Test wird immer in der CI-Umgebung übergeben, während er immer mit einem AbstractMethodError auf meiner lokalen Umgebung fehlschlägt. In beiden Fällen verwende ich Gradle (2.7).


Der Fehler:

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 Ausgabe:

  • CI (wo es funktioniert):

    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 (wo es nicht):

    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) 
    

Ich erwarte dies eine Art javac zu sein Fehler, bei dem der Compiler nicht alle erforderlichen Bridge-Methoden hinzufügen kann (der Code wird ohne Warnungen kompiliert oder e Richtig). In IntelliJ IDEA tritt das Problem sowohl unter Verwendung von javac als auch des Eclipse-Compilers auf.

+0

Präsentieren Sie, was Sie bereits als das minimale Setup bewiesen haben, um den Fehler zu reproduzieren? Es gibt viele Schnittstellen hier, wenn es nicht mit weniger gezeigt werden kann, sieht das Problem ziemlich komplex aus. –

+0

Dekompilieren Sie die 'MutableSet.class', die zur Laufzeit in Ihrer lokalen Umgebung ausgeführt wird. Gibt es dort eine Standardmethode? –

+0

@DraganBozanovic, ja, es gibt Bridge-Methoden für alle Super-Interface '$ plus' Methoden. In der Klasse 'ArraySet' gibt es jedoch keine Bridge-Methoden. – Clashsoft

Antwort

0

(Antwort basiert auf Autors Kommentar oben gemacht: Problem wurde gelöst):

eine vollständige Reinigung tun und das Problem so gut fixiert wieder aufzubauen.

Nichtsdestotrotz musste irgendwann ein Fehler die fehlerhaften Binärdateien verursacht haben.