b73: IllegalAccessError: tried to access class java.util.stream.BaseStream

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jan 17 03:29:40 PST 2013


If I fix the compiler to do the right thing, I get a 292 crash:

Source:

interface A {
     void m();
}

interface B extends A { }

class Test {
     public static void main(String[] args) {
         B b = ()->{};
         b.m();
     }
}


javap snippet:

BootstrapMethods:
     0: #17 invokestatic 
java/lang/invoke/LambdaMetafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
       Method arguments:
         #18 invokeinterface B.m:()V
         #19 invokestatic Test.lambda$0:()V
         #20 ()V

Output:

Exception in thread "main" java.lang.IncompatibleClassChangeError
     at 
java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:383)
     at Test.main(intf05702.java:60)
Caused by: java.lang.IllegalAccessException: no such method: 
B.m()void/invokeInterface
     at java.lang.invoke.MemberName.makeAccessException(MemberName.java:749)
     at 
java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:870)
     at 
java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1032)
     at 
java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1264)
     at 
java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:381)
     ... 1 more
Caused by: java.lang.AbstractMethodError: B.m()V
     at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
     at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:842)
     at 
java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:867)
     ... 4 more


Ideas?

Maurizio


On 16/01/13 22:56, Remi Forax wrote:
> On 01/16/2013 11:46 PM, Maurizio Cimadamore wrote:
>> On 16/01/13 19:21, Remi Forax wrote:
>>> On 01/16/2013 04:51 PM, Paul Sandoz wrote:
>>>> On Jan 16, 2013, at 4:17 PM, Dmitry Bessonov 
>>>> <dmitry.bessonov at oracle.com> wrote:
>>>>
>>>>> import java.util.Arrays;
>>>>> import java.util.stream.Stream;
>>>>>
>>>>> public class IllegalAccessErrorTest {
>>>>>
>>>>>       public static void main(String[] args) {
>>>>>
>>>>>           Stream stream = Arrays.asList("a", "b").stream();
>>>>>           System.err.println("iterator = " + stream.iterator());
>>>>>           Iterable iterable = stream::iterator;
>>>>>           System.err.println("iterable = " + iterable);
>>>>>       }
>>>>> }
>>>>>
>>>>> when compiled/run on b73 the output is:
>>>>>
>>>>>
>>>>> iterator = java.util.stream.ReferencePipeline$6 at 3256a5
>>>>> Exception in thread "main" java.lang.IllegalAccessError: tried to 
>>>>> access
>>>>> class java.util.stream.BaseStream from class IllegalAccessErrorTest
>>>>>       at IllegalAccessErrorTest.main(IllegalAccessErrorTest.java:10)
>>>>>
>>>> Interesting. BaseStream was made package private.
>>>>
>>>> Looks like a bug in the runtime translation of the method reference.
>>> No, it's compiler bug, if you use javap -verbose you can see that the
>>> class file uses BaseStream::Iterator instead of Stream::iterator as
>>> argument of the bootstrap method.
>> Uhm - right, but the referenced method is in fact 
>> BaseStream::iterator since Stream does not override it... ,
>
> yes,
>  but iterator() is visible in Stream but not in BaseStream (because 
> BaseStream is not visible).
>
> by example, the code:
>   Stream stream = ...
>   stream.iterator();
> is translated to an invokeinterface Stream.iterator()
>
> Likewise, Stream::Iterator should be translated to a method reference 
> Stream.iterator and not BaseStream.iterator.
>
>>
>> Maurizio
>
> Rémi
>
>>>> Paul.
>>> Rémi
>>>
>>>>
>>>>> with b72 no exceptions are seen
>>>>>
>>>>> -Dmitry
>>>>>
>>>>>
>>>
>>
>



More information about the lambda-dev mailing list