java.lang.NoSuchMethodError avec compareTo sur des lambda + generics
Une fois n'est pas coutume, je suis coincé. J'essaie de limiter mon code au maximum ici.
Pour une raison X ou Y, java pédale dans la semoule quand je mélange des lambda et des interfaces Generic.
Soit l'interface HistoryData, qui défini en gros 2 méthode: getStartDate et getEndDate.
Soit l'interface bien connue Comparable.
Soit la class Contract
Code:
public class Contract implements Comparable<Contract>, HistoryData
Soit la méthode statique générique
Code:
1 2 3 4 5 6 7 8 9 10
| public static <T extends HistoryData & Comparable<T>> T getContinuousEnd(Collection<? extends T> collection, T startingPoint){
return collection.stream()
.sorted() // natural order, oldest first thus
.filter((c)->c.compareTo(startingPoint)<=0)
// Now we have all contracts older or same than current one
// Keep only consecutive ones
.filter(HistoryData.continuousPredicate())
// and now last element
.reduce((previous, current) -> current).orElse(null);
} |
appelée comme ceci:
Code:
1 2 3 4
|
public Contract getContractEmployementEnd(Contract referenceContract){
return getContinuousEnd(getContracts(), referenceContract);
} |
j'obtiens cette joyeuseté sans le moindre warning de compilation (donc théoriquement le compilateur me dit que le typechecking est parfait dans mon code :aie:)
Code:
1 2 3 4 5 6 7 8 9 10
| java.lang.NoSuchMethodError: be.rmi.intranet.rh.HistoryData.compareTo(Ljava/lang/Object;)I
at *******.HistoryData.lambda$4(HistoryData.java:165)
at *******.HistoryData$$Lambda$6/21894472.test(Unknown Source)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.TreeMap$KeySpliterator.forEachRemaining(TreeMap.java:2741)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479) |
Ce qui correspond à la ligne
Code:
.filter((c)->c.compareTo(startingPoint)<=0)
Est-ce qu'il y a un moyen de s'en sortir sans devoir changer l'interface de mon Contract en
Code:
public class Contract implements Comparable<Object>, HistoryData
??