On Wed, 24 Jun 2026 07:18:15 GMT, Jaikiran Pai <[email protected]> wrote:
>> getstatic is specified/implement to throw ISE if a strictly-initialized >> static field is unset. The reflection APIs are implemented to do the same >> but it doesn't surface in the API docs. >> >> Field.getXXX is updated to specify the exception. Each getXXX method already >> specifies EIIE so it doesn't look out of place, and seems preferable to >> putting in the class description of isStrictInit. Doing the equivalent in >> MH/VH would add a lot of clutter so instead factory methods that produce a >> MH/VH to read a static field are updated. These methods already specify that >> they may provoke the field's class to be initialized so an additional >> sentence on invoking/operating-on while initializing the class doesn't look >> out of place. >> >> StrictInitializingTest tests MH/VH access to a field that is unset but we >> don't seem to have tests for Field. Adding a simple test for Field.get and >> the MH/VH produced from a Field, and another test for FIeld.isStrictInit so >> its behavior when preview features are disabled and enabled is tested. >> >> --------- >> - [x] I confirm that I make this contribution in accordance with the >> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai). > > src/java.base/share/classes/java/lang/reflect/Field.java line 493: > >> 491: * @throws ExceptionInInitializerError if the initialization >> provoked >> 492: * by this method fails. >> 493: * @throws IllegalStateException if the current thread is >> initializing the > > Hello Alan, is the mention of "current thread" intentional here? The case > I've in mind is something like: > > > // get an uninitialized class > final Class k = Class.forName("Foo", false, someClassLoader); > // get hold of the field of interest > final Field f = k.getDeclaredField("someStaticStrictInitField"); > > // trigger class initialization in Thread T1 > Thread t1 = () -> {doSomethingToTriggerClassInit(k);} > t1.start(); > > // access the (static) strict init field in thread T2, expect it to fail with > IllegalStateException, because some other thread is initializing the class > currently > Thread t2 = () -> {f.get(null);} > t2.start(); > > > > I think this scenario where some other thread calls `Field.get()` when the > field's `Class` is being initialized is possible, isn't it? > II think this scenario where some other thread calls Field.get() when the > field's Class is being initialized is possible, isn't it? The thread executing the class initializer can freely access the class fields (or methods). Attempts by other threads to access the class fields (or methods) will block until the class is initialized. With strictly-initialized fields, the field must be initialized before it can be read. For strictly-initialized static fields, if the thread initializing the class attempts to read the field before it has been initialized then the getstatic will throw ISE. The reflective APIs to the same. So yes, "current thread" is intentional here. ------------- PR Review Comment: https://git.openjdk.org/valhalla/pull/2572#discussion_r3465569664
