IncompatibleClassChangeError example
Paul Sandoz
paul.sandoz at oracle.com
Wed Jun 19 08:33:07 PDT 2013
Hi Peter.
Replace "this.get()" with just "get()" or "Value.this.get()" and it runs OK, but i am not even sure it is entirely correct looking at the diffs of javap output of not this vs. this.
e.g. public vs. private static interface for the method lambda$0.
When using "this.get()" the following method is generated by javac:
private static java.lang.Object lambda$0(java.util.function.Function);
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: aload_0
2: invokeinterface #4, 1 // InterfaceMethod get:()Ljava/lang/Object;
7: invokeinterface #5, 2 // InterfaceMethod java/util/function/Function.apply:(Ljava/lang/Object;)Ljava/lang/Object;
12: areturn
LineNumberTable:
line 1: 0
line 9: 2
To my untrained eye that looks dodgy with the two aload_0 instructions, it's trying to invoked the Value.get method on the Function interface. I would expect the method to have two args.
Paul.
16c16
< #36 invokeinterface Test$Value.lambda$0:(Ljava/util/function/Function;)Ljava/lang/Object;
---
> #36 invokestatic Test$Value.lambda$0:(Ljava/util/function/Function;)Ljava/lang/Object;
23c23
< #2 = InvokeDynamic #0:#38 // #0:lambda$:(LTest$Value;Ljava/util/function/Function;)Ljava/util/function/Supplier;
---
> #2 = InvokeDynamic #0:#38 // #0:lambda$:(Ljava/util/function/Function;)Ljava/util/function/Supplier;
57c57
< #36 = MethodHandle #9:#49 // invokeinterface Test$Value.lambda$0:(Ljava/util/function/Function;)Ljava/lang/Object;
---
> #36 = MethodHandle #6:#49 // invokestatic Test$Value.lambda$0:(Ljava/util/function/Function;)Ljava/lang/Object;
59c59
< #38 = NameAndType #51:#52 // lambda$:(LTest$Value;Ljava/util/function/Function;)Ljava/util/function/Supplier;
---
> #38 = NameAndType #51:#52 // lambda$:(Ljava/util/function/Function;)Ljava/util/function/Supplier;
73c73
< #52 = Utf8 (LTest$Value;Ljava/util/function/Function;)Ljava/util/function/Supplier;
---
> #52 = Utf8 (Ljava/util/function/Function;)Ljava/util/function/Supplier;
95c95
< stack=4, locals=2, args_size=2
---
> stack=3, locals=2, args_size=2
98,102c98,101
< 4: aload_0
< 5: aload_1
< 6: invokedynamic #2, 0 // InvokeDynamic #0:lambda$:(LTest$Value;Ljava/util/function/Function;)Ljava/util/function/Supplier;
< 11: invokespecial #3 // Method Test$SuppliedValue."<init>":(Ljava/util/function/Supplier;)V
< 14: areturn
---
> 4: aload_1
> 5: invokedynamic #2, 0 // InvokeDynamic #0:lambda$:(Ljava/util/function/Function;)Ljava/util/function/Supplier;
> 10: invokespecial #3 // Method Test$SuppliedValue."<init>":(Ljava/util/function/Supplier;)V
> 13: areturn
107,108c106,107
< 0 15 0 this LTest$Value;
< 0 15 1 mapper Ljava/util/function/Function;
---
> 0 14 0 this LTest$Value;
> 0 14 1 mapper Ljava/util/function/Function;
111,112c110,111
< 0 15 0 this LTest$Value<TT;>;
< 0 15 1 mapper Ljava/util/function/Function<-TT;+TR;>;
---
> 0 14 0 this LTest$Value<TT;>;
> 0 14 1 mapper Ljava/util/function/Function<-TT;+TR;>;
115,116c114,115
< public java.lang.Object lambda$0(java.util.function.Function);
< flags: ACC_PUBLIC, ACC_SYNTHETIC
---
> private static java.lang.Object lambda$0(java.util.function.Function);
> flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
118,119c117,118
< stack=2, locals=2, args_size=2
< 0: aload_1
---
> stack=2, locals=1, args_size=1
> 0: aload_0
127,132d125
< LocalVariableTable:
< Start Length Slot Name Signature
< 0 13 0 this LTest$Value;
< LocalVariableTypeTable:
< Start Length Slot Name Signature
< 0 13 0 this LTest$Value<TT;>;
On Jun 18, 2013, at 9:29 AM, Peter Levart <peter.levart at gmail.com> wrote:
> Just a reminder that the following problem is still present...
>
> Regards, Peter
>
> On 06/09/2013 05:24 PM, Peter Levart wrote:
>> Hi,
>>
>> When I compile and run the following program with the latest tip of
>> lambda repo:
>>
>>
>> import java.util.function.Function;
>> import java.util.function.Supplier;
>>
>> public class ICCEBug {
>>
>> interface Value<T> extends Supplier<T> {
>> default <R> Value<R> map(Function<? super T, ? extends R>
>> mapper) {
>> return new SuppliedValue<>(() -> mapper.apply(this.get()));
>> }
>> }
>>
>> static class SuppliedValue<T> implements Value<T> {
>> private final Supplier<T> supplier;
>>
>> SuppliedValue(Supplier<T> supplier) {
>> this.supplier = supplier;
>> }
>>
>> @Override
>> public T get() {
>> return supplier.get();
>> }
>> }
>>
>> public static void main(String[] args) {
>> Value<String> name = () -> "Peter";
>> Value<String> sentence = name.map(nm -> "Hello " + nm + "!");
>> System.out.println(sentence.get());
>> }
>> }
>>
>>
>>
>> ... I get the following exception:
>>
>> Exception in thread "main" java.lang.IncompatibleClassChangeError:
>> Class ICCEBug$$Lambda$2 does not implement the requested interface
>> ICCEBug$Value
>> at ICCEBug$Value.lambda$0(ICCEBug.java:17)
>> at ICCEBug$Value$$Lambda$3.get(Unknown Source)
>> at ICCEBug$SuppliedValue.get(ICCEBug.java:30)
>> at ICCEBug.main(ICCEBug.java:37)
>>
>>
>>
>> It looks like something is not compiled correctly.
>>
>> Regards, Peter
>>
>
>
More information about the lambda-dev
mailing list