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