MethodHandles.lookup errors where publicLookup is ok
Alan Bateman
alan.bateman at oracle.com
Wed Sep 3 09:09:26 UTC 2025
On 02/09/2025 20:36, Charles Oliver Nutter wrote:
>
> However... why doesn't `findVirtual()` request read access to the
> given class's module before erroring? Presumably this is what the
> reflected call and the `publicLookup()` logic does. Worst case, it
> would raise an error because it cannot gain such access. If there's
> another down side to requesting read access automatically when read
> access is clearly required, I'd like to know about it... because now I
> have to do it manually anyway.
Method handles are aligned with bytecode behavior, this includes access
checks in the MH factory methods. If you were to inject code into module
org.jruby.dist with a reference to a class in module X then any attempt
in org.jruby.dist to access a class in module X would fail with
IllegalAccessError. org.jruby.dist's module does not declare "requires
X" and so org.jruby.dist does not read X.
Lookup.publicLookup is the minimally trusted lookup to create method
handles to public fields and methods. This necessitated the addition of
the UNCONDITIONAL access mode even though it doesn't correspond to a
modifier in the access flags. It means that the access check done with
the publicLookup is closer to what you see with core reflection (where
readability is assumed) rather than bytecode. This may seem complicated
but it's not something that most developers will ever need to deal with
directly.
>
> As regards diagnosing this then I think we need improve the
> IllegalAccessExceptions exception messages. A lot of effort went
> into JDK 9 to ensure that the IAE thrown in the core reflection
> access spelled out the reason why the access check failed. Most
> reflection based frameworks used core reflection at the time. We
> should have put more effort into the having the IAE exception
> messages in j.l.invoke as "is not accessible" makes it hard to
> diagnose.
>
>
> Raising an error saying it "is not accessible" is also rather
> misleading when it actually **is** accessible
It's not accessible from code in module org.jruby.dist so not accessible
with the Lookup obtained from lookup(). That said, we need to improve
the IAE exception messages. A lot of effort went into exception messages
thrown by setAccessible/Method.invoke/Field.xxx where as the IAE
exception messages thrown by the MH factory methods are less helpful.
BTW: Your first message has "symbolic reference class is not accessible:
class jdk.proxy4.$Proxy49" which suggests that the JRuby code may be
attempting the findVirtual for the method in the proxy implementation
class rather than the method in the interface class. You might to check
that.
-Alan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250903/0f4f468d/attachment-0001.htm>
More information about the core-libs-dev
mailing list