Slow performance of StackWalker.getCallerClass() vs Reflection.getCallerClass()

Mandy Chung mandy.chung at oracle.com
Fri Jul 5 16:26:44 UTC 2019



On 7/2/19 9:54 PM, Kasper Nielsen wrote:
> On Tue, 2 Jul 2019 at 18:50, Mandy Chung <mandy.chung at oracle.com> wrote:
>> I'm not getting how getCallerClass is used and related to access check.
>> Can you elaborate?
> Caller sensitive methods are viral, in the sense that if you invoke a caller
> sensitive method in the JDK, as a library on behalf of a client (without
> having a lookup object). You need to perform the same access checks as the JDK
> does. That is, checking that the client that calls you - the library - has the
> right access rights. The caller sensitive methods in the JDK cannot do this,
> because there is no way for them to see that the library is merely a proxy
> acting on behalf of a client.
>
> Consider a very simple serialization library with one method
>    String serializeToString(Object o) // prints out the value of every field
> with an implementation in a module called SER. And two modules M1, M2 that uses
> SER (For example, via a ServiceLoader). Both M1 and M2 are open to SER in order
> for the serializer to serialize the objects in each of the two modules.
> However, M1 and M2 are not open towards each other. So it is not the intention
> that, for example, some code from M1 can call it with objects from M2 and have
> them serialized or vice versa. However, this is entire possible unless
> serializeToString() performs access checks on the caller. All M1 has to do is
> get a hold of an object from M2 and then call serializeToString() with it.
> There is no way the jdk can check this, it just sees an object from M2 which
> is open to SER. It has no idea it is actually M1 trying to serialize it. So
> the only way for this to work as intended is for serializeToString to check
> that the caller matches the object. And unless you pass around Lookup objects
> the only way you can do it, is similar to how the jdk does it; by looking at the
> calling class. Reflection::getCallerClass is not available outside of the JDK,
> so StackWalker is the only way to do this.
>
> I've put up an example at https://github.com/kaspernielsen/modulestest.
> Calling M2Use.main will serialize an object from M1 even though it M1 is
> not open to M2.
>
> As noted in another thread this gets further complicated because all the access
> control code is buried in internal jdk classes. In this example you more or less
> have to reimplement AccessibleObject.checkCanSetAccessible yourself.
> In the end I don't think it is realistic to expect library developers to get
> this right.
>

M1 and M2 are open to SER.  SER can call `privateLookupIn` to get a 
lookup on M1's class and then it can use M1's lookup to call 
accessClass.   An alternative idea is to have the caller to pass its 
lookup to serializeToString method to access if the caller lookup object 
has access to the given object.   Would that be a plausible solution?

Mandy


More information about the core-libs-dev mailing list