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

bitter_fox bitterfoxc at gmail.com
Thu Jan 17 09:23:41 PST 2013


Hi, Maurizio.
I think your fix is correct.

The exception looks like a bug of 292.

We can make a similar exception by the following code:

import java.lang.invoke.*;

public class Test
{
    interface I1
    {
        void m();
    }

    interface I2 extends I1 {}

    public static void main(String[] args) throws Exception
    {
        MethodHandles.Lookup l = MethodHandles.lookup();
        MethodType mt = MethodType.methodType(void.class);

        l.findVirtual(I2.class, "m", mt);
    }
}

This is the exception:
Exception in thread "main" java.lang.IllegalAccessException: no such
method: Test$I2.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.findVirtual(MethodHandles.java:653)
    at Test.main(Test.java:18)
Caused by: java.lang.AbstractMethodError: Test$I2.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)
    ... 3 more


It seems it was already reported and will be fixed.
http://bugs.sun.com/view_bug.do?bug_id=7087658
http://planetjava.org/java-openjdk-core-libs-devel/2012-03/msg00254.html

Regards,
bitter_fox


2013/1/17 Maurizio Cimadamore <maurizio.cimadamore at oracle.com>

> 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