On 11/01/2016 11:02 AM, Andrew Dinn wrote:
On 01/11/16 15:35, David M. Lloyd wrote:
On 11/01/2016 10:09 AM, Andrew Dinn wrote:
There is a very easy way to provide tightly controlled access to a
framework. Export access to e.g. jdk.internal.misc.Unsafe or e.g.
java.lang.[invoke].MethodHandles to a nominated module provided by your
framework then arrange for that module to hand out Lookups (or better
MethodHandles) to framework code as and when they are needed via a
private channel. You can do arrange that with a single addExports option
on the command line and a very small amount of setup code to establish
the private channel
I don't see how this is safer though. You're proposing to hand all the
keys (or none) to modules which don't need all the keys, whereas I
propose that a module should only gain incremental additional access on
a grant basis.
No, I'm suggesting handing the keys to a single module provided by your
framework -- which module will then use a key to open a room on demand
for your code and your code only. That means the privilege can be
granted using one command line switch with use of that privilege
controlled by a runtime mechanism of your choosing.
Yes, however that means that I'm on the hook to make sure that the keys
aren't mislaid. And given the fact of open modules - which already
semantically grants me privileges - requiring a special command line
switch (which is itself undesirable) and custom code to enable those
privileges in the *preferred* manner (i.e. MethodHandles) seems
backwards when open modules would already grant me the ability to
utilize a much finer instrument albeit with the legacy approach (i.e.
reflection). It seems quite logical to extend this mechanism to the
preferred MethodHandle approach instead, and forget about Unsafe and
anything like it, which I think is in everyone's best interests in the
long term.
At least Rémi's approach requires a specific grant and non-Unsafe
vector, though as I said the weaknesses (of his first approach) are that
the grant must come from the target class (programmatically) instead of
being a static declaration ("opens" is a natural fit for this if I
understand the proposal correctly). The other weakness is that it
requires class init, but that's purely a consequence of requiring a
programmatic grant as far as I understand.
I did actually suggest a way of avoiding the use of Unsafe. You give
your nominated module full reflective access to java.lang.invoke
allowing it to create Lookup instances (it can actually just create a
single all privileges lookup and use this to clone others). You don't
need to insert a class into java.lang.invoke to do this. You simply add
one exports directive on the command line.
That is marginally better, of course, but I think the rest of my
objections still stand against this argument.
Rémi's newest Gist uses an annotation, which is closer but not quite on
the target IMO. An annotation cannot be module-deployment-agnostic in
the way that I outlined previously (hence
#IndirectQualifiedReflectiveAccess); ultimately accessibility
information ought to come from the module configuration itself.
If you implement a module with the ability to hand out Lookup instances
you can use whatever control model you like. For example, you might park
an instance which hands out Lookups in a location only available to your
framework or ensure that any caller asking for a Lookup belongs in a
package implemented by your framework or whatever you want. the point is
that once you have granted a class in our code the ability to create
Lookups you can implement whatever runtime access control you want.
Clearly,as John said, you need to do that responsibly.
regards,
Andrew Dinn
-----------
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander
--
- DML