Towards better serialization

Anthony Vanelverdinghe at
Sun Jun 16 18:54:22 UTC 2019

[my apologies for any double e-mails, sending to amber-dev now as suggested]


I’d like to chime in on the discussion w.r.t. encapsulation relaxation, as brought up by Rémi.

While I agree that the proposed usage of `open` would be a natural extension of the existing concept, I was always under the impression that `open` was intended as a “temporary" migration aid. That frameworks were supposed to move away from reflection and adopt solutions based on `MethodHandles.Lookup` instead. So I'm surprised to see the use of reflection promoted now.

An advantage of open packages, is that they are able to specify whom they're exporting to. So I can say: `opens foo.ser to some.ser.framework` and `opens foo.cdi to some.cdi.framework`. And the CDI framework would be unable to reflect on the foo.ser package, and vice versa. In contrast, an `open` member would always be an unqualified open, and it would not communicate to the reader *why* it was opened. Now if the member is annotated with `@Deserializer`, I could assume it was opened for serialization purposes, but I cannot be sure that this was really the reason. And for open members without a well-known annotation, it would be totally unclear what the purpose of their open-ness is.

Another advantage of open packages, is that glancing over the module descriptor is sufficient to know what's accessible, module-wide, both at compile- and run-time. By allowing `open` on individual members, this would no longer be possible (or at least: you'd need a tool to inspect the module & list all open members for you).

If a finer-grained mechanism is deemed necessary, I'd propose instead to allow annotations in the `opens` clauses of a module descriptor: `opens @Serializer, at Deserializer to foo.ser`. This would then allow the `foo.ser` module reflective access to all members that are annotated with either of the given annotations. This would retain the advantages of being able to open reflective access to a single module, as well as keeping the module descriptor self-contained in terms of what's accessible and what not.

Kind regards,
From: amber-spec-observers <amber-spec-observers-bounces at> on behalf of Brian Goetz <brian.goetz at>
Sent: Wednesday, June 12, 2019 1:01:38 AM
To: forax at
Cc: amber-spec-experts
Subject: Re: Towards better serialization

>> There are surely a range of options here, but the one you propose takes
>> two orthogonal considerations and couples them -- which is reinventing
>> one of the sins of original serialization.  (And, other frameworks
>> (e.g., dependency injection, mocking, etc) have similar need for dynamic
>> access to members that are not intended as part of the "front door" API
>> anyway.)
> you want to special mechanism for the serialization, no ?

No, I want an _unspecial_ mechanism for the serialization.  I want the
user to code with ordinary constructors and pattern extractors, and have
serialization just call them, informed by metadata (which is how we pass
information to frameworks.)

> Otherwise, we already have java.lang.invoke.Lookup.privateLookupIn() and the open keyword on the module/package.

Yes, Lookup is a possible implementation mechanism for such an relaxed
encapsulation mechanism.  But aligning with what modules do, just at a
finer-grained level, is extending an existing concept in a natural way,
which seems preferable to adding a new concept to the programming model.

> It already encodes the semantics "we believe in encapsulation but sometimes we don't".
> Having a finer grain version of "open" goes against what was decided by the JPMS EG in my humble opinion.

We could surely ditch it, and say "If you want to have serializable
classes in your module, open the whole module."  And some users might be
OK with that, even though it is squashing a bug with a tank.  But, in
reality this _is_ a new category of accessibility modifier -- that a
method is dynamically accessible regardless of its static
accessibility.  And having this appear clearly in the source file makes
it much more obvious what is going on.  The high-order bit here is
"banish the magic".

More information about the amber-dev mailing list