Discussion: Prefer passing MethodHandles.Lookup over @CallerSensitive
Johannes Kuhn
info at j-kuhn.de
Fri Apr 21 13:44:11 UTC 2023
Hi,
Instead of making new and existing methods @CallerSensitive, such
methods could instead take a MethodHandles.Lookup as method argument.
Library authors are often told that they could ask their users to pass a
MethodHandles.Lookup to obtain internal access instead of using things
like AccessibleObject::setAccessible.
I hope OpenJDK would follow that advice as well, IMHO the broader use of
MethodHandles.Lookup would make things easier for both OpenJDK
deverlopers & library authors.
tl;dr: Have one @CallerSensitive method to rule them all:
MethodHandles.lookup()
-----
1. Conceptually a @CallerSensitive method has a hidden parameter - the
caller class, which does not appear in source- or bytecode. A
MethodHandles.Lookup parameter is explicit.
2. Most @CallerSensitive methods are listed in the Secure Coding
Guidelines for Java SE[1]. When adding new @CallerSensitive methods it
should always be considered if those methods need to be listed in that
document as well.
This list should also not increase indefinitely, as each use of a method
listed there needs to be carefully checked to avoid security
vulnerabilities.
Using a method taking a MethodHandles.Lookup needs the same scrutiny -
but because of the explicit nature this is evident from looking at use-site.
3. Methods that take an explicit MethodHandles.Lookup compose better
with other methods that do the same - for example, a library could pass
the lookup it received from its client to a core API, thereby acting on
behalf of the client.
4. When a @CallerSensitive method is looked up from
MethodHandles.Lookup, it needs to be bound to the caller.
This binding can be expensive in the worst case (load of an hidden class
+ erasing the signature to ([Ljava/lang/Object;)Ljava/lang/Object;)
5. Making existing methods @CallerSensitive can lead to small backwards
compatibility issues - as the public lookup can't lookup those methods
anymore.
-----
A @CallerSensitive method have one benefit over passing a
MethodHandles.Lookup: It has a nicer API.
This might be fine for the restricted methods that Panama introduces.
New methods that need to take the caller into account could for example
add instead an overload that takes an explicit MethodHandles.Lookup as
argument. The one without that argument could work as if
`MethodHandles.publicLookup()` was passed to the other.
-----
Closing words:
This is my personal opinion, and might be totally wrong.
For now, my goal is just to start a discussion.
I explicitly don't ask about changing existing @CallerSensitive methods.
- Johannes
[1]: https://www.oracle.com/java/technologies/javase/seccodeguide.html#9-8
More information about the core-libs-dev
mailing list