Just curious, would klass.getModule().isExported(klass.getPackageName(), 
JRUBY_MODULE) be a more accurate test here?

Chen
________________________________
From: core-libs-dev <[email protected]> on behalf of Charles 
Oliver Nutter <[email protected]>
Sent: Thursday, September 4, 2025 11:41 AM
To: Alan Bateman <[email protected]>
Cc: [email protected] <[email protected]>
Subject: Re: MethodHandles.lookup errors where publicLookup is ok

On Wed, Sep 3, 2025 at 4:09 AM Alan Bateman 
<[email protected]<mailto:[email protected]>> wrote:
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.

Ok, I understand. Play with sharp tools, get cut. And given the evolution of MH 
and Lookup over the years I'm not surprised my original expectations from a 
decade ago don't quite match the modern reality of JPMS.

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.

I guess it will just take me some time to internalize the reality of "can't be 
read until read access is requested" for cases that "magically" work through 
traditional reflection. This discussion helps.

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.

Fair point. We have typically assumed that if Modifier.isPublic(klass) was 
true, we are good to go ahead and bind that class and its methods in our Java 
integration layer and indy call sites. I'm testing a patch that adds 
JRUBY_MODULE.canRead(klass.getModule()) to that requirement and so far it fixes 
the original issue and does not appear to regress any other features. Instead 
of binding Function.apply as Proxy49.apply, we should only bind it against the 
public interface.

- Charlie


Reply via email to