JVM does not match JVMS regarding array component types?

David Holmes david.holmes at oracle.com
Thu Apr 14 07:51:04 UTC 2022


Hi Anton,

On 14/04/2022 12:17 am, Anton W. Haubner wrote:
> 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?

See https://bugs.openjdk.java.net/browse/JDK-8181144

Cheers,
David

> 
> 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