<p dir="ltr">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.<br>
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</p>
<br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Dec 9, 2024, 19:07 Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><u></u>
<div>
<font size="4" face="monospace">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.</font><br>
<br>
<br>
<div>On 12/8/2024 11:52 AM, Florian Weimer
wrote:<br>
</div>
<blockquote type="cite">
<pre>* Remi Forax:
</pre>
<blockquote type="cite">
<blockquote type="cite">
<pre>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.
</pre>
</blockquote>
<pre>
Why not sending the lookup object here :
var csv = CSVReader.newReader(r, Row.class, MethodHandles.lookup());
</pre>
</blockquote>
<pre>
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.
</pre>
<blockquote type="cite">
<blockquote type="cite">
<pre>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.
</pre>
</blockquote>
<pre>
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.
</pre>
</blockquote>
<pre>
Is this already under discussion somewhere? I've seen some references
to generalizing pattern matching to custom types, but nothing along
what you describe.
</pre>
</blockquote>
<br>
</div>
</blockquote></div>