Constructing records through reflection and module restrictions
Brian Goetz
brian.goetz at oracle.com
Mon Dec 9 18:45:11 UTC 2024
The `opens` clause of a module descriptor indeed can be qualified, just
as the exports clause can:
ModuleDirective:
requires {RequiresModifier} ModuleName ;
exports PackageName [to ModuleName {, ModuleName}] ;
opens PackageName [to ModuleName {, ModuleName}] ;
uses TypeName ;
provides TypeName with TypeName {, TypeName} ;
On 12/9/2024 1:22 PM, Olexandr Rotan wrote:
>
> Little of topic here, but what I was lacking with opening is opens *
> to X (similar to exports * to X). For example, I want my module to be
> open to code that I trust like spring framework, but not accessible to
> some 3rd party API wrappers. Something like this would be really
> helpful in situations when working with sensitive user data, because
> otherwise you either have to give up access control using open module
> or open packages one by one to each module which is virtually
> unmaintainable.
> Putting everything "open" is not really an option since like 95% of
> code has to be open to reflection if working with IoC containers and ORM`s
>
>
> On Mon, Dec 9, 2024, 19:07 Brian Goetz <brian.goetz at oracle.com> wrote:
>
> There is a better approach than passing around the Lookup (which
> requires everyone to coordinate around the Lookup capability): use
> open modules. THe concept of "open module" was designed for
> exactly this purpose: to allow packages to be "exported for
> reflection" so that frameworks can reflect over them more
> liberally than bytecode linkage would permit. If you put your
> domain objects in a package that is opened (either to the
> framework, or to everyone), no need to play games with Lookup.
>
>
> On 12/8/2024 11:52 AM, Florian Weimer wrote:
>> * Remi Forax:
>>
>>>> Syntax-wise, it is very tempting to use this with very localized
>>>> record types for various kinds of custom deserialization scenarios.
>>>> For example, to read a CSV file with two colums, something like this
>>>> could be used:
>>>>
>>>> record Row(String name, int index) {}
>>>> var csv = CSVReader.newReader(r, Row.class);
>>>> while (true) {
>>>> var row = csv.readRow();
>>>> if (row == null)
>>>> break;
>>>> // Use the row variable.
>>>> ...
>>>> }
>>>>
>>>> But it would equally work for SQL result set rows, binary structures,
>>>> and so on.
>>> Why not sending the lookup object here :
>>>
>>> var csv = CSVReader.newReader(r, Row.class, MethodHandles.lookup());
>> Thanks. Not surpringly, this works for constructor access. It should
>> help with using defineHiddenClass() as well if I read the
>> documentation correctly (although maybe I can get what I want just
>> using method handles). Syntax-wise, I think it's okay, although it
>> will certainly look like magic to newcomers if this programming
>> pattern ever catches on (and similarly in other APIs that use
>> reflective access behind the covers). But from a conceptual
>> perspective, it's really clear.
>>
>> It appears that MethodHandles.lookup() uses an intrisified
>> getCallerClass(), so it's probably not necessary to turn this into
>> MethodHandles::lookup, to the lookup when it is not needed.
>>
>>>> I think some people use interfaces and java.lang.reflect.Proxy for a
>>>> similar purpose, hoping that method declaration order matches
>>>> reflection order (not a good idea, I know). As far as I can see, the
>>>> proxy mechanism does not perform a module encapsulation check and can
>>>> create instaces at points where a regular class declaration with an
>>>> implements clause could not reference to the interface. Records would
>>>> be a better replacement because they provide ordering of components.
>>> If you use an abstract deconstructors/pattern method, you get the declaration order
>>>
>>> interface Row {
>>> abstract deconstructor (String name, int index) Row(); // or a similar syntax
>>> }
>>>
>>> ...
>>> Row(var name, var index) = csv.readRow();
>>> // use name and index here
>>>
>>> and i suppose that j.l.r.Proxy will be updated to implement such pattern.
>> Is this already under discussion somewhere? I've seen some references
>> to generalizing pattern matching to custom types, but nothing along
>> what you describe.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241209/f87dd9bd/attachment.htm>
More information about the amber-dev
mailing list