JVM does not match JVMS regarding array component types?

Anton W. Haubner anton.haubner at outlook.de
Wed Apr 13 14:17:00 UTC 2022


Follow up on the conditions under which types should become visible 
during debugging:

JDB uses the JDI methods VirtualMachine.allClasses() and 
VirtualMachine.classesByName() to look up types
(See com.sun.tools.example.debug.tty.Env.getReferenceTypeFromToken()).

Looking at the JDI documentation and the specification of the underlying 
JDWP, one normally should be able to look up all loaded types:

https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jdi/com/sun/jdi/VirtualMachine.html#allClasses()
https://docs.oracle.com/en/java/javase/11/docs/specs/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_AllClasses

https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jdi/com/sun/jdi/VirtualMachine.html#classesByName(java.lang.String)
https://docs.oracle.com/en/java/javase/11/docs/specs/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_ClassesBySignature

So maybe the JPDA backend agent of OpenJDK does not respect this 
specification?


On 4/13/22 16:14, Anton W. Haubner wrote:
> 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