10

Diciamo che ho la seguente gerarchia di classe:strano comportamento Metodo di default con diverse versioni di Java

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 
} 

Come si può vedere, solo la classe MutableSet fornisce un'implementazione per il metodo $plus. In un caso di test, sto chiamando questo metodo su un'istanza di tipo ArraySet. Il test passa sempre nell'ambiente CI, mentre fallisce sempre con un AbstractMethodError sul mio ambiente locale. In entrambi i casi, sto usando Gradle (2.7).


l'errore:

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

  • CI (in cui opera):

    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) 
    
  • locale (in cui viene a mancare):

    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) 
    

Mi aspetto che questo sia una sorta di javac bug, in cui il compilatore non riesce ad aggiungere tutti i metodi bridge richiesti (il codice viene compilato senza avvisi o e rrors). In IntelliJ IDEA, il problema si verifica sia utilizzando javac che il compilatore Eclipse.

+0

Stai presentando quello che hai già dimostrato essere l'installazione minima per riprodurre l'errore? Ci sono molte interfacce qui, se non possono essere dimostrate con meno, il problema sembra piuttosto complesso. –

+0

Decompila il 'MutableSet.class' che viene eseguito in runtime nell'ambiente locale. C'è un metodo predefinito lì? –

+0

@DraganBozanovic, sì, ci sono metodi bridge per tutti i metodi super-interface '$ plus'. Non ci sono metodi bridge nella classe 'ArraySet', però. – Clashsoft

risposta

0

(La risposta è stata effettuata sulla base di commento dell'autore sopra: problema è stato risolto):

Facendo un completo e ricostruire risolto il problema pure.

Tuttavia, a un certo punto deve essersi verificato un errore che ha causato i file binari difettosi.