Constructing records through reflection and module restrictions
Olexandr Rotan
rotanolexandr842 at gmail.com
Mon Dec 9 18:22:35 UTC 2024
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/5254f997/attachment-0001.htm>
More information about the amber-dev
mailing list