Anonymous structs have strange issues with scala and intellij in ea+44

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Feb 20 10:52:50 UTC 2019


I found the issue. Consider this example:

$ cat test.h

struct server {
    struct {
       int x;
       int y;
    } events;
};


in the classfile for test$server.class, jextract is omitting an inner 
class attribute which lists the anon class. That is, a regularly 
compiled class (with javac) will feature an inner class attribute like this:

InnerClasses:
   public static #6= #5 of #15;            // anon$test_h$19=class 
test$anon$test_h$19 of class test
   public static #10= #1 of #15;           // server=class test$server 
of class test

Whereas the jextracted class will be like this:

InnerClasses:
   public static #20= #2 of #19;           // server=class test$server 
of class test


In other words, jextract is failing to mention, in the InnerClasses 
attributes, all _uses_ of nested classes - which creates problem to all 
tools. The classfile generated by jextract does not behave according to 
the JVM specification, which mandates that whenever there's a constant 
pool entry modelling an inner class, a corresponding entry to the 
InnerClasses attribute should be added.

Thanks for the report.

Maurizio

On 20/02/2019 10:19, Maurizio Cimadamore wrote:
> Hi Mark,
> if my hunch is correct, I believe attempting to reproduce with Java 
> code might be impossible.
>
> The problem has to do with the naming scheme AND something in the 
> bytecode that jextract generates which seems to confuse IDE and other 
> tools.
>
> Redundant signature attributes (such as the one pointed out in my 
> other email) might be a part of the puzzle.
>
> Rather than attempting to reproduce with Java - it would be more 
> helpful, I think, to try to come up with a simple header which 
> exhibits the same issues when programming against it. I plan to do 
> that next and see if I'm successful. Hopefully I just need an anon 
> struct.
>
> Maurizio
>
> On 20/02/2019 01:59, Mark Hammons wrote:
>> Thanks Maurizio,
>>
>> I have been trying to reproduce this on my own and I cannot get the 
>> same behavior. An inner class of a struct with a name like 
>> anon$backend_h$555 works fine. In the case of every anonymous class 
>> in this code, scala can't handle it, nor can intellij. I've attached 
>> the javap of the other anonymous struct bindings I've found as well 
>> as their host classes. I hope this helps determine the issue.
>>
>> One thing I've noticed in the class files I've given you is they all 
>> end with something like this:
>>
>> Signature: #3                           // 
>> Ljava/lang/Object;Ljava/foreign/memory/Struct<Lwlroots/backend_headers/session$anon$session_h$751;>;
>> RuntimeVisibleAnnotations:
>>   0: #8(#9=s#10,#11=I#12,#13=I#14)
>>     java.foreign.annotations.NativeLocation(
>>       file="/usr/include/wlr/backend/session.h"
>>       line=43
>>       column=2
>>     )
>>   1: #15(#16=s#17)
>>     java.foreign.annotations.NativeStruct(
>>       value="[${wl_signal}(destroy)](anon$session_h$751)"
>>     )
>>
>> I dunno if that's the issue or not, I'm not familiar enough with 
>> bytecode to know that. However, I haven't been able to create an 
>> innerclass with the anon$backend_h$114 naming scheme that has that 
>> kind of ending information. I'll try some more tomorrow and see if I 
>> can't produce a java example that produces the same issues.
>>
>> Mark
>>
>> On 2/20/19 2:14 AM, Maurizio Cimadamore wrote:
>>> The signature attributes look in order - actually there are some 
>>> attributes which are not even needed, as in this case:
>>>
>>> public abstract wlroots.backend$anon$backend_h$444 events$get();
>>>     descriptor: ()Lwlroots/backend$anon$backend_h$444;
>>>     flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
>>>     Signature: #36                          // 
>>> ()Lwlroots/backend$anon$backend_h$444;
>>>
>>>
>>> It seems like the code generator always emits a signature...
>>>
>>> What I suspect is that the tools are confused by the '$' sign, and 
>>> they are tricked into thinking that "444" is an inner class of 
>>> "backend_h".
>>>
>>> I will do some more experiments of this though.
>>>
>>> Thanks
>>> Maurizio
>>>
>>>
>>> On 20/02/2019 00:28, Mark Hammons wrote:
>>>> Sure,
>>>>
>>>> I'd like to note one thing quickly. Before I was extracting the jar 
>>>> with an archive extracter and calling javap on the raw classfiles. 
>>>> Just now I tried "javap -p -v -cp wlroots.jar 
>>>> wlroots.backend.anon$backend_h$444" and it couldn't find the class, 
>>>> but "javap -p -v -cp wlroots.jar 
>>>> wlroots.backend.anon.backend_h.444" had it able to find the class 
>>>> in question. Ditto for  "javap -p -v -cp wlroots.jar 
>>>> wlroots.backend_headers.session.anon.session_h.751". I'm attaching 
>>>> my wlroots.jar along with the javap of wlr_backend.class.
>>>>
>>>> This seems to be a recurring issue with the anonymous structs 
>>>> generated by jextract.
>>>>
>>>> Mark
>>>>
>>>> On 2/20/19 1:04 AM, Maurizio Cimadamore wrote:
>>>>> Thanks,
>>>>> can you please also post the dump of the 'wlr_backend' struct?
>>>>>
>>>>> Maurizio
>>>>>
>>>>> On 19/02/2019 23:56, Mark Hammons wrote:
>>>>>> Here's the javap dump. Tell me if there's anything else I can get 
>>>>>> you.
>>>>>>
>>>>>> Mark
>>>>>>
>>>>>>
>>>>>> On 2/20/19 12:44 AM, Maurizio Cimadamore wrote:
>>>>>>>
>>>>>>> On 19/02/2019 23:29, Jorn Vernee wrote:
>>>>>>>> I tried to reproduce the problem without using jextract as 
>>>>>>>> well, but was not able to, so the bug seems to be up to a 
>>>>>>>> particularity of the classes generated by jextract. I'm not 
>>>>>>>> sure if the bug should be attributed to jextract or IntelliJ 
>>>>>>>> though. 
>>>>>>>
>>>>>>> I wonder if this could be due to some missing (or, most likely, 
>>>>>>> just bad) Signature attributes in the resulting classfile?
>>>>>>>
>>>>>>> Would you be able to post a 'javap -v -p' dump of the classfile, 
>>>>>>> so that we can take a look at it and look for anomalies?
>>>>>>>
>>>>>>> Maurizio
>>>>>>>


More information about the panama-dev mailing list