<div dir="ltr">Can you elaborate more on how <font face="monospace">form.line($.address.city);</font><font face="arial, sans-serif"> uses the identity of </font><font face="monospace">city</font><font face="arial, sans-serif">? <br><br>How does </font><font face="monospace">Backend.find(Person.class, By.field($.address.zip, 8000));</font><font face="arial, sans-serif"> figure out that </font><font face="monospace">$.address.zip</font><font face="arial, sans-serif"> refers to the corresponding field in </font><font face="monospace">Address</font><font face="arial, sans-serif">?</font></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Mon, Dec 1, 2025 at 1:56 PM Remi Forax <<a href="mailto:forax@univ-mlv.fr">forax@univ-mlv.fr</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">----- Original Message -----<br>
> From: "Bruno Eberhard" <<a href="mailto:bruno.eberhard@pop.ch" target="_blank">bruno.eberhard@pop.ch</a>><br>
> To: "valhalla-dev" <<a href="mailto:valhalla-dev@openjdk.org" target="_blank">valhalla-dev@openjdk.org</a>><br>
> Sent: Wednesday, November 26, 2025 10:43:30 AM<br>
> Subject: Valhalla breaks minimal-j framework<br>
<br>
> Hi,<br>
> <br>
> I really like the concepts and the gains you make with Valhalla. But it<br>
> breaks some essential points of my framework called «minimal-j» (on<br>
> <a href="https://github.com/BrunoEberhard/minimal-j" rel="noreferrer" target="_blank">https://github.com/BrunoEberhard/minimal-j</a> ). I would kindly ask if you<br>
> can provide a replacement for what is not possible in Valhalla anymore.<br>
> <br>
> Let me show the problem and then propose a solution. In the minimal<br>
> design all fields of a class representing a business entity (only those)<br>
> are public. No getter or setter. Then a static constant $ is defined<br>
> like this:<br>
> <br>
>  public class Person {<br>
>       public static final Person $ = Keys.of(Person.class);<br>
> <br>
>       @NotEmpty<br>
>       public Integer number;<br>
> <br>
>       @Size(100)<br>
>       @Searched<br>
>       @NotEmpty<br>
>       public String name;<br>
>       <br>
>       public final Address address = new Address();<br>
> }<br>
> <br>
> With the $ constant there is a reference to the fields of the class.<br>
> With theses references a UI can be specified:<br>
> <br>
>       var form = new Form<Person>();<br>
>       form.line($.number);<br>
>       form.line($.name);<br>
>       form.line($.address.city);<br>
> <br>
> Or a query to the persistence layer can be formulated:<br>
> <br>
>       Backend.find(Person.class, By.field($.name, "Bruno"));<br>
>       Backend.find(Person.class, By.field($.address.zip, 8000));<br>
> <br>
> In the background the framework fills the fields of the $ constant with<br>
> values that are later used to identify which field should be used. For<br>
> this identity is vital. Things like "new String(..)" and "new<br>
> Integer(..)" is used to make $.number unique.<br>
> <br>
> If Integers loose their identity this is now longer feasable.<br>
> <br>
> A possible replacement for this trick would be references to fields.<br>
> Best in this way:<br>
> <br>
>       Backend.find(Person.class, By.field(Person::name, "Bruno"));<br>
> <br>
> Person::name should result in a java.lang.reflect.Field<br>
> <br>
>       Backend.find(Person.class, By.field(Person::address::zip, 8000));<br>
> <br>
> Here Person::address::zip should result in a java.lang.reflect.Field[]<br>
> or in a new class containing chained Fields.<br>
> <br>
> Of course I could instead write getter and setter and the use<br>
> Person::getName . But Person::getAddress::getZip doesn't work. And I<br>
> would really like not to have getter and setter (for which I have to<br>
> check all names and parameters are correct). Lombok or Kotlin hide<br>
> getter and setter. But I don't really like hiding something. Especially<br>
> if it is not really needed.<br>
> <br>
> So if it is possible to add this construct to the java language it would<br>
> make me really happy. Otherwise I would never be able to use a Java<br>
> version which contains Valhalle for this kind of framework.<br>
<br>
Integers, and others are marked as value-based classes<br>
(<a href="https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/doc-files/ValueBased.html" rel="noreferrer" target="_blank">https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/doc-files/ValueBased.html</a>)<br>
since quite some time, so your framework is currently violating this non-enforced spec.<br>
<br>
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.<br>
<br>
I've seen a mocking framework having the same issue a lot time ago before and after Integers where cached.<br>
<br>
They moved to a representation using interfaces + dynamic proxies instead of classes.<br>
<br>
public interface Person {<br>
  public static final Person $ = Keys.of(Person.class);<br>
<br>
  @NotEmpty<br>
  public int number();<br>
<br>
  @Size(100)<br>
  @Searched<br>
  @NotEmpty<br>
  public String name();<br>
<br>
  public final Address address();<br>
}<br>
<br>
with the information being stored out of the line in ThreadLocal (I believe you can now use ScopeValue for that)<br>
instead of using a special return value.<br>
<br>
On the positive side, you do not have to use Integer anymore, you can use int (see numbers()),<br>
on the negative side, it's obviously not backward compatible with your existing framework. <br>
<br>
> <br>
> regards<br>
<br>
regards,<br>
Rémi<br>
</blockquote></div>