top | item 43539321

(no title)

bironran | 11 months ago

A cursory glance at "setAccessible" usage reveals popular libraries such as serializers like gson and jaxb, class manipulation and generation like cglib, aspectj and even jdk.internal.reflect, testing frameworks and libraries including junit, mockito and other mocking libraries, lombok, groovy, spring, and the list goes on and on.

My bet is that this will be yet another "checked exception" or "module system", where many applications now need to add "--add-opens". If you'll use ANY of many of the more popular frameworks or libraries you'll end up giving this assurance away, which will make library developers not able to rely on it and we're back to square one.

discuss

order

pron|11 months ago

We've addressed that in the JEP. Serialization libraries have a special way to circumvent this (until we get Serialization 2.0), and mocking libraries may, indeed, need to set the flag, but they're rarely used in production, so if they don't enjoy some new optimisation -- no big deal.

BTW, this JEP does not apply to setAccessible generally, as that's been restricted since JDK 16, but only to the particular (and more rare) use of setAccessible to mutate instance final fields. As the JEP says, static final fields, records' internal instance fields, and final instance fields of hidden classes cannot be mutated with that approach currently, so it's never been something that's expected to work in all cases.

LadyCailin|11 months ago

Would be nice to have a single “--test-mode” flag that is only meant to be set when running tests, and allows for all this leniency, (add opens, etc) in a single flag.

PathOfEclipse|11 months ago

setAccessible is also used to be able to access private fields, and not just to be able to write to final fields. Most libraries shouldn't need to set final fields, and I say this as someone who was very against when they deprecated java.lang.misc.Unsafe. I've only had to set a final field once in my career and it was related to some obscure MySql/JDBC driver bug/workaround. This particular deprecation seems very sensible to me.

eastbound|11 months ago

So how should GSON initialize an object?

The theory is, go through the constructor. However, some objects are designed to go through several steps before reaching the desired state.

If GSON must deserialize {…, state:”CONFIRMED”}, it needs to call new Transaction(account1, account2, amount), then .setState(STARTED) then .setState(PENDING) then .setState(PAID) then .setState(CONFIRMED) ? That’s the theory of the constructor and mutation methods guarding the state, so that it is physically impossible to reach a wrong state.

There is a convention that deserialization is an exception to this theory: It should be able to restore the object as-is, after for example a transfer over the wire. So it was conventionally enabled to set final variables of the object, but only at initialization and only for its own good. It was assumed that, even though GSON could reach a state that was unachievable through normal means, it was, after all, the role of the programmer to add the right annotations to avoid this.

So how do we do it now?

merb|11 months ago

Yeah like the module system. Looks good on paper, is probably hard to deal with. There are still tons of popular libraries that have no module-info. Java does evolve, but the direction it does is so weird. And than the tooling is strange and it’s worse that there are basically two build tools, both with their upsides and downsides but they still feel more complicated than tools for other languages like cargo, go (if you consider that), msbuild (the modern csproj stuff/slnx)

gf000|11 months ago

Gradle is a general build tool, while cargo/go are only for their respective languages.

The moment you need to run some code from another language on your code to generate some other code or whatever, they break down, while Gradle can be used for pretty much anything.

In other words, cargo/go only solve the cache/parallelize/resolve task dependencies problem for "hard coded" special cases, the moment you strive away from that you are in a world of pain.

PaulHoule|11 months ago

My impression is that this will be painful for the code I work on because the libraries you mention depend on being able to modify private and/or final fields.

xxs|11 months ago

private fields are no issue