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