MethodHandles.lookup errors where publicLookup is ok
Charles Oliver Nutter
headius at headius.com
Tue Sep 2 16:22:27 UTC 2025
On Tue, Sep 2, 2025 at 10:56 AM Chen Liang <chen.l.liang at oracle.com> wrote:
> Hi Charlie,
> This is definitely a bug in the JDK, but I need more investigation to
> ensure if the issue lies in Lookup or Proxy. I guess this might relate to
> the fact that proxy dynamic modules are open to java.base as an
> implementation artifact, because the public lookup has Object.class as its
> lookup class.
>
> Since proxy has different module configurations depending on whether it
> has module-private or package-private interfaces, can you share a minimal
> setup where you can replicate this issue? I tried replicating on:
>
> Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class<?>
> []{Runnable.class}, (_, _, _) -> {return null;})
>
> In jshell, and failed to replicate your failure with Lookup::accessClass.
>
I will try to come up with a non-JRuby reproduction, but I'm not sure when
I'll get around to that.
JRuby itself runs as a module and both the `lookup()` and `findVirtual()`
for the Proxy's method implementation would be happening from within that
modularized code. I would expect that your reproduction attempt should
demonstrate the error if `lookup().findVirtual()` happened from an external
(non-java.base) module.
The reproduction with JRuby is simple... unpack the 10.0.2.0 tarball from
jruby.org or run "./mvnw" in a JRuby git checkout, then "bin/jruby
example.rb" should demonstrate the problem using the short reproduction
code I provided here:
https://github.com/jruby/jruby/issues/8987#issuecomment-3245755989
Note that my naive attempt to convert all `lookup()` along this path in
JRuby to `publicLookup()` did indeed break a bunch of other cases where
"more than public" access is needed for findVirtual/findStatic:
https://github.com/jruby/jruby/pull/8989
This is the sort of situation I hoped to avoid by using `lookup()` under
the expectation that it would treat all `find*` as though they were
accessed naturally (i.e. not via java.lang.invoke) from that point in the
surrounding class.
> publicLookup has UNCONDITIONAL access so it assumes readability (like
> core reflection). The lookup object obtained with MethodsHandles.lookup
> does not so there may be cases where the caller needs to use
> Module.addReads to add the read edge at runtime. I can't tell if this is
> what you are running it but if you could create a small test case
My first thought after reading this was that perhaps I should be using
`unreflect` rather than doing my own `findVirtual` but since that requires
a Lookup object I'd expect I'm right back in the same situation.
- Charlie
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250902/d41895b9/attachment.htm>
More information about the core-libs-dev
mailing list