----- Mail original ----- > De: "Remi Forax" <fo...@univ-mlv.fr> > À: "Paul Bakker" <paul.bak...@luminis.eu> > Cc: jigsaw-dev@openjdk.java.net > Envoyé: Mardi 1 Novembre 2016 00:57:47 > Objet: Re: New proposal for #ReflectiveAccessToNonExportedTypes: Open modules > & open packages
> Hi Paul, > I think you can already sketch an implementation of the proposal now by using > either an annotation processor + a jlink plugin, or by a jlink plugin + a > bytecode processor tool. > I believe that you can push the information needed by the meta-framework to > fulfill requests by adding some method calls inside the static initializer of > the classes that are annotated. > The runtime part can be something along that line > > https://gist.github.com/forax/1511fae2273f04273ff9463c6fbbdfbc > > Instead of providing method handles as John suggests, i provide the lookup > object which is less secure. > And the Class object in the map are stored as strong ref instead of being an > ephemeron (the lambda used as value in the map has also a strong reference on > the class). After shower edit, i've updated the gist to use a ClassValue + a CAS so there is no strong ref to the classes now. > > Rémi Rémi > > ----- Mail original ----- >> De: "Paul Bakker" <paul.bak...@luminis.eu> >> À: jigsaw-dev@openjdk.java.net >> Envoyé: Lundi 31 Octobre 2016 18:06:27 >> Objet: Re: New proposal for #ReflectiveAccessToNonExportedTypes: Open >> modules & >> open packages > >> The proposal looks very good! Thanks for listening to the voiced concerns. >> When can we expect a new prototype containing the proposed features? >> >> Thanks, >> >> Paul >> >> On Fri, Oct 28, 2016 at 3:38 PM John Rose <john.r.r...@oracle.com> wrote: >> >>> On Oct 27, 2016, at 9:07 AM, mark.reinh...@oracle.com wrote: >>> > >>> > Further comments most welcome, as usual! >>> >>> >>> +100 for *qualified* opens; this puts an important limit on deep >>> reflection. >>> >>> My main concern with reflection is to avoid "falling off the encapsulation >>> cliff" >>> the first time a user module wishes to open itself up for deep reflection. >>> By such a "cliff" I mean that when deep reflection is allowed, potentially >>> any name in the module can be inspected. Even of only 0.01% of names >>> are actually inspected, tools for reorganizing code must assume that 100% >>> of the names *might* be inspected, at some point in the future, by the >>> allowed party. >>> >>> So qualified opens is a partial solution. And, I think it is exactly >>> right for >>> today, because it can be extended tomorrow. I.e., it is future-friendly. >>> I'll explain by sketching a concept called "moderate reflection", or "MR". >>> >>> A fuller solution would allow other tools to make conclusions about more >>> specific limitations on the actual extent of the deep reflection. Call >>> such >>> an extent-limited reflection moderate reflection, where "moderation" is >>> declared statically by some sort of flexible declarative rule set. In >>> this way >>> tools could make more detailed conclusions about the encapsulation of >>> particular names in the module. >>> >>> For future JDK releases we can consider layering of this qualified opens, >>> by creating a trusted, parameterized meta-framework ("Moderate Reflection") >>> to which a user module can be qualified-open. This meta-framework can >>> then perform deep reflection on behalf of self-describing "moderately >>> reflecting" >>> client frameworks. User modules would not directly open themselves to any >>> module other than MR. >>> >>> The advantage would come when the client frameworks explicitly declare >>> their >>> self-restraint ("moderation") in reflection. For example, the "Foo" >>> framework >>> might limit itself to names annotated with @FooFrameworkHook. >>> >>> An AOT compiler (or other jlink-time reorganization tool) would (1) note >>> that >>> some user module bar is qualified-open only to Moderate Reflection, and >>> has an export (maybe qualified) to a Foo framework. At runtime, (2) the >>> Foo framework would ask Moderate Reflection to reflect into bar. >>> Moderate Reflection would (3) check the self-limitation on Foo, and also >>> ensure that bar exports (though doesn't open) to Foo. MR would then >>> gain the requested access and delegate it back to Foo. Finally, (4) the >>> AOT compiler would free itself to omit metadata for unexported names >>> not visible to moderate reflection. >>> >>> (Method handles are a good way to grant access, since they can >>> be delegated from MR to Foo without re-authorizing Foo. Core >>> Reflection re-authorizes on every access, which awkwardly >>> requires deep reflection on usage, as well as initial lookup.) >>> >>> Moderate Reflection might also look at metadata on the bar module >>> (besides its module exports) to impose further limits on reflection. >>> Thus, MR-specific metadata might prevent MR from granting bar >>> access to normally-trusted frameworks that bar doesn't trust, if >>> bar can blacklist them for itself in a place that MR checks. >>> >>> And so on. None of this needs to be built into the module system. >>> To gain the benefit of it, basic parametric policies need to be >>> implemented, >>> adopted by client frameworks, and used by tools to perform optimizations. >>> >>> A typical optimization is "tree shaking", where a class or method that is >>> never used is dropped from the application. Or, if it is used in a way >>> that >>> can be inlined locally, the metadata can still be dropped. In either case, >>> making code go dead is an important ingredient to many optimizations. >>> > > > — John