JVM does not match JVMS regarding array component types?
Anton W. Haubner
anton.haubner at outlook.de
Wed Apr 13 14:14:12 UTC 2022
Hi!
Thank you for this hint.
The output of `java -Xlog:class+load ArrayTest` contains
```
...
[0.242s][info][class,load] java.lang.Void source: jrt:/java.base
[0.242s][info][class,load] Test source: file:/home/anton/<...>
[0.242s][info][class,load] jdk.internal.misc.TerminatingThreadLocal$1
source: jrt:/java.base
...
```
This is the only place where the component type "Test" is mentioned.
If I understand this output correctly, then the "Test" class has
actually been created.
Now I wonder, under which conditions a created type becomes visible
through the JDI.
Best regards,
Anton Haubner
On 4/13/22 15:02, Volker Simonis wrote:
> Just to make sure this is not an issue with jdb, could you please run
> your example program with "-Xlog:class+load" and check the output?
>
> Anton W. Haubner <anton.haubner at outlook.de> schrieb am Mi., 13. Apr.
> 2022, 11:12:
>
> Hi!
>
> I am not sure if this is the right place to ask these questions. At
> first glance, the "jls-jvms-spec-comments" mailing list looks more
> appropriate but its description says that that list "is solely a drop
> box for reports".
> Therefore, if I am out-of-place here, please direct me to the
> appropriate mailing list.
>
> My question is about the behaviour of the JVM which seemingly does
> not
> match the JVMS specification when it comes to lazy-linking and
> empty arrays.
>
> I noticed that regarding lazy-linking strategies and resolution, the
> JVMS states that if an array type is resolved whose element type is a
> reference type, then
>
> "a symbolic reference to the class or interface representing the
> element type is resolved [...] recursively." [1]
>
> More specifically, the `anewarray` instruction requires the
> resolution
> of the component type when executed [2].
>
> However, while inspecting programs with the JDI, I observed that when
> creating an empty array, the component type of the array is
> actually not
> loaded.
> You can observe this as follows:
>
> 1. Compile the following program with `javac -g`:
>
> ```
> class Test { }
>
> public class ArrayTest {
> public static void main(String[] args) {
> var x = new Test[] {};
> }
> }
>
> ```
>
> 2. Executing `javap -v ArrayTest` will confirm that when stopping the
> program on line 6, `anewarray` must have been executed.
>
> 3. Run the following commands in `jdb`:
>
> stop at ArrayTest:6
> run ArrayTest
> class Test
>
> 4. It will say "Test is not a valid id or class name.", i.e. the
> class
> "Test" has not been loaded, even though it should have been
> because it
> is the component type of Test[] for which an instance has been
> created.
>
> 5. If you change line 5 to "var x = new Test[] {new Test()};" jdb
> will
> actually return information about "Test", that is, the class is
> loaded.
>
> From these observations I conclude, that the component type of an
> array
> type is not loaded, if only empty instances of the array type are
> created.
> I wonder, why this does not violate the specification of the JVMS
> at [1]
> and [2]
>
> (I am working with Java 11, so so far I tested this only for
> OpenJDK 11)
>
> [1] Section 5.4.3.1, Java Virtual Machine Specification, Java 11:
> https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.4.3.1
> [2]
> https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html#jvms-6.5.anewarray
>
>
>
More information about the discuss
mailing list