RFR: 8353835: Implement JEP 500: Prepare to Make Final Mean Final [v3]

Erik Gahlin egahlin at openjdk.org
Sat Sep 27 15:44:18 UTC 2025


On Sat, 27 Sep 2025 13:10:04 GMT, Alan Bateman <alanb at openjdk.org> wrote:

>> Implementation changes for [JEP 500: Prepare to Make Final Mean Final](https://openjdk.org/jeps/500).
>> 
>> Field.set (and Lookup.unreflectSetter) are changed to allow/warn/debug/deny when mutating a final instance field. JFR event recorded if final field mutated. Spec updates to Field.set, Field.setAccessible and Module.addOpens to align with the proposal in the JEP.
>> 
>> HotSpot is updated to add support for the new command line options. To aid diagnosability, -Xcheck:jni reports a fatal error when a mutating a final field with JNI, and -Xlog:jni=debug can help identity when JNI code mutates finals. For now, JNI code is allowed to set the "write-protected" fields System.in/out/err, we can re-visit once we change the System.setIn/setOut/setErr methods to not use JNI (I prefer to keep this separate to this PR because there is a small startup regression to address when changing System.setXXX).
>> 
>> There are many new tests. A small number of existing tests are changed to run /othervm as reflectively opening a package isn't sufficient. Changing the tests to /othervm means that jtreg will launch the agent with the command line options to open the package.
>> 
>> Testing: tier1-6
>
> Alan Bateman has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 23 commits:
> 
>  - Merge branch 'master' into JDK-8353835
>  - Merge branch 'master' into JDK-8353835
>  - Improve setters and test cleanup
>  - Merge branch 'master' into JDK-8353835
>  - Merge branch 'master' into JDK-8353835
>  - Review feedback
>  - Change ciField::initialize_from to use is_mutable_static_final, suggested by Vladimir Ivanov
>  - Merge branch 'master' into JDK-8353835
>  - Test cleanup
>  - More improvements
>  - ... and 13 more: https://git.openjdk.org/jdk/compare/af8fb20a...545557d9

The JFR changes look good, but by adding @jdk.jfr.internal.RemoveFields("duration") to the jdk.jfr.events.FinalFieldMutationEvent class, the event is emitted without a duration, and the threshold setting can be removed from default.jfc and profile.jfc. There is no longer a need to update TestActiveSettingEvent.java. All the events listed there, e.g.  VirtualThreadSubmitFailedEvent, should be removed. I've filed a bug for [this](https://bugs.openjdk.org/browse/JDK-8368809)

Is it known whether the top frame of the stack traces originates in the method that mutates the field, or in a JDK internal class?

There are two ways to control this. The cheapest is to set the stack trace offset in the jdk.jfr.internal.PlatformEventType::determineStackTraceOffset method, but this may not be feasible if the depth depends on how the call reaches the offer method. In those cases, the jdk.jfr.internal.StackFilter annotation can be used on the jdk.jfr.events.FinalFieldMutationEvent class to filter out specific classes. To prevent bit rot, event.getStackTrace().getFrames().getFirst().getMethod().getName() may be checked in the test.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/25115#issuecomment-3341864819


More information about the core-libs-dev mailing list