Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

"Not a parameterized type!" when indexing a record with a compact constructor and an annotated parameterized types #218

Closed
nithril opened this issue Jun 2, 2022 · 6 comments
Assignees
Milestone

Comments

@nithril
Copy link

nithril commented Jun 2, 2022

Hello,

Considering this java record with a compact constructor:

public record MyRecord(List<@NotEmpty String> list) {
    public MyRecord {
        list = null;
    }
}

When indexing the record

Indexer indexer = new Indexer();
indexer.indexClass(MyRecord.class);

Jandex throws a java.lang.IllegalArgumentException: Not a parameterized type!

@Ladicek
Copy link
Contributor

Ladicek commented Jun 2, 2022

The error occurs when parsing a type annotation on the record constructor. If the constructor is removed, the class file is parsed just fine. This is how javap -v -p shows the constructor:

  public test.MyRecord(java.util.List<java.lang.String>);
    descriptor: (Ljava/util/List;)V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Record."<init>":()V
         4: aload_0
         5: aload_1
         6: putfield      #7                  // Field list:Ljava/util/List;
         9: return
      LineNumberTable:
        line 6: 0
        line 7: 9
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      10     0  this   Ltest/MyRecord;
            0      10     1  list   Ljava/util/List;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0      10     1  list   Ljava/util/List<Ljava/lang/String;>;
    MethodParameters:
      Name                           Flags
      list
    Signature: #37                          // (Ljava/util/List<Ljava/lang/String;>;)V
    RuntimeVisibleTypeAnnotations:
      0: #28(): FIELD, location=[TYPE_ARGUMENT(0)]
        test.NotEmpty

It seems to me that the target_type value of the type annotation is wrong -- it's FIELD (0x13), but it should be METHOD_PARAMETER (0x16). Congrats, you found a bug in javac :-)

Jandex should be able to ignore that. I'll try to figure something out.

@Ladicek
Copy link
Contributor

Ladicek commented Jun 2, 2022

Also, it seems the problem only appears with a compact constructor. As a workaround, you can use a normal constructor instead of a compact one:

public record MyRecord(List<@NotEmpty String> list) {
    public MyRecord(List<@NotEmpty String> list) {
        this.list = list;
    }
}

@Ladicek Ladicek self-assigned this Jun 2, 2022
@nithril
Copy link
Author

nithril commented Jun 2, 2022

It seems to me that the target_type value of the type annotation is wrong -- it's FIELD (0x13), but it should be METHOD_PARAMETER (0x16). Congrats, you found a bug in javac :-)

The merit goes to you :)

Are you sure it should be METHOD_PARAMETER? AFAIU compact constructor is operating on the fields of the class

@Ladicek
Copy link
Contributor

Ladicek commented Jun 2, 2022

Actually a compact constructor has implicitly declared parameters, per the JLS (8.10.4.2. Compact Canonical Constructors). In this case, there's just one parameter, and its type contains a type annotation.

The record also implicitly declares a component field (8.10.3. Record Members). That field's type also contains a type annotation, and it seems to me that javac simply takes the type of the field it generated and pushes it into the constructor parameter list. Which is fine, until there are type annotations :-)

EDIT: the record also implicitly declares an accessor method, but type annotations on its return type seem to be correct.

@Ladicek
Copy link
Contributor

Ladicek commented Jun 2, 2022

In any case, I have a workaround for Jandex that will just drop the invalid type annotation.

@Ladicek
Copy link
Contributor

Ladicek commented Jun 2, 2022

Done in #219. Thanks for the report!

@Ladicek Ladicek closed this as completed Jun 2, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants