Valhalla breaks minimal-j framework
Ethan McCue
ethan at mccue.dev
Mon Dec 1 19:37:57 UTC 2025
One more question: How does the code today work around things like the
small integer cache?
On Mon, Dec 1, 2025 at 2:04 PM Ethan McCue <ethan at mccue.dev> wrote:
> Can you elaborate more on how form.line($.address.city); uses the
> identity of city?
>
> How does Backend.find(Person.class, By.field($.address.zip, 8000)); figure
> out that $.address.zip refers to the corresponding field in Address?
>
> On Mon, Dec 1, 2025 at 1:56 PM Remi Forax <forax at univ-mlv.fr> wrote:
>
>> ----- Original Message -----
>> > From: "Bruno Eberhard" <bruno.eberhard at pop.ch>
>> > To: "valhalla-dev" <valhalla-dev at openjdk.org>
>> > Sent: Wednesday, November 26, 2025 10:43:30 AM
>> > Subject: Valhalla breaks minimal-j framework
>>
>> > Hi,
>> >
>> > I really like the concepts and the gains you make with Valhalla. But it
>> > breaks some essential points of my framework called «minimal-j» (on
>> > https://github.com/BrunoEberhard/minimal-j ). I would kindly ask if you
>> > can provide a replacement for what is not possible in Valhalla anymore.
>> >
>> > Let me show the problem and then propose a solution. In the minimal
>> > design all fields of a class representing a business entity (only those)
>> > are public. No getter or setter. Then a static constant $ is defined
>> > like this:
>> >
>> > public class Person {
>> > public static final Person $ = Keys.of(Person.class);
>> >
>> > @NotEmpty
>> > public Integer number;
>> >
>> > @Size(100)
>> > @Searched
>> > @NotEmpty
>> > public String name;
>> >
>> > public final Address address = new Address();
>> > }
>> >
>> > With the $ constant there is a reference to the fields of the class.
>> > With theses references a UI can be specified:
>> >
>> > var form = new Form<Person>();
>> > form.line($.number);
>> > form.line($.name);
>> > form.line($.address.city);
>> >
>> > Or a query to the persistence layer can be formulated:
>> >
>> > Backend.find(Person.class, By.field($.name, "Bruno"));
>> > Backend.find(Person.class, By.field($.address.zip, 8000));
>> >
>> > In the background the framework fills the fields of the $ constant with
>> > values that are later used to identify which field should be used. For
>> > this identity is vital. Things like "new String(..)" and "new
>> > Integer(..)" is used to make $.number unique.
>> >
>> > If Integers loose their identity this is now longer feasable.
>> >
>> > A possible replacement for this trick would be references to fields.
>> > Best in this way:
>> >
>> > Backend.find(Person.class, By.field(Person::name, "Bruno"));
>> >
>> > Person::name should result in a java.lang.reflect.Field
>> >
>> > Backend.find(Person.class, By.field(Person::address::zip, 8000));
>> >
>> > Here Person::address::zip should result in a java.lang.reflect.Field[]
>> > or in a new class containing chained Fields.
>> >
>> > Of course I could instead write getter and setter and the use
>> > Person::getName . But Person::getAddress::getZip doesn't work. And I
>> > would really like not to have getter and setter (for which I have to
>> > check all names and parameters are correct). Lombok or Kotlin hide
>> > getter and setter. But I don't really like hiding something. Especially
>> > if it is not really needed.
>> >
>> > So if it is possible to add this construct to the java language it would
>> > make me really happy. Otherwise I would never be able to use a Java
>> > version which contains Valhalle for this kind of framework.
>>
>> Integers, and others are marked as value-based classes
>> (
>> https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/doc-files/ValueBased.html
>> )
>> since quite some time, so your framework is currently violating this
>> non-enforced spec.
>>
>> I don't blame you, not at all, i've done the same in ASM at some point in
>> time, but we have to fix the errors of the past ; Integer should be a
>> lightweight boxing with no identity guarantee ; because it improve 99.9% of
>> the existing codes.
>>
>> I've seen a mocking framework having the same issue a lot time ago before
>> and after Integers where cached.
>>
>> They moved to a representation using interfaces + dynamic proxies instead
>> of classes.
>>
>> public interface Person {
>> public static final Person $ = Keys.of(Person.class);
>>
>> @NotEmpty
>> public int number();
>>
>> @Size(100)
>> @Searched
>> @NotEmpty
>> public String name();
>>
>> public final Address address();
>> }
>>
>> with the information being stored out of the line in ThreadLocal (I
>> believe you can now use ScopeValue for that)
>> instead of using a special return value.
>>
>> On the positive side, you do not have to use Integer anymore, you can use
>> int (see numbers()),
>> on the negative side, it's obviously not backward compatible with your
>> existing framework.
>>
>> >
>> > regards
>>
>> regards,
>> Rémi
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-dev/attachments/20251201/ae6b6745/attachment.htm>
More information about the valhalla-dev
mailing list