Uploaded image for project: 'Sling'
  1. Sling
  2. SLING-12359

Sling Models: Support constructor injection for Java Record classes

    XMLWordPrintableJSON

Details

    Description

      Java 14 introduced support for record classes, and Apache Sling 12 by default runs with Java 17, allowing the use of records.

      Although Apache Sling 12 supports record classes, the current latest version of Apache Sling Models Implementation does not fully support injection in relation to records. Specifically, for records, the Apache Sling Models Implementation does support constructor injection similarly to a usual class if there is an explicit constructor annotated with `javax.inject.Inject`:

      @Model(
              adaptables = {Resource.class, SlingHttpServletRequest.class},
              defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED
      )
      public record StudentModel(String name, int age) {
      
          @Inject
          public StudentModel(
                  @ValueMapValue(name = "name") @Default(values = "unknown")
                  String name, 
                  @ValueMapValue(name = "age") @Default(intValues = 0)
                  int age
          ) {
              this.name = name;
              this.age = age;
          }
      }
      

      However, for records, Apache Sling Models Implementation does not support constructor injection if there is an implicit constructor. Such a constructor cannot be annotated with `javax.inject.Inject` and will not be picked up during injection. Therefore, such a Sling Model will not be instantiated at all:

      @Model(
              adaptables = {Resource.class, SlingHttpServletRequest.class},
              defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED
      )
      public record StudentModel(
              @ValueMapValue(name = "name") @Default(values = "unknown")
              String name,
              @ValueMapValue(name = "age") @Default(intValues = 0)
              int age
      ) {}
      

      The above issue should be addressed by introducing support for injection in records' implicit constructors.

      Note:

      1. For records, only constructor injection is supported since records cannot have instance fields (code with such fields will not compile).
      2. Apache Sling Models Implementation is currently based on Java 8 and may also be executed in a Java 8 environment. Therefore, the records check should be introduced via dynamic loading of the `java.lang.Record` class.

      Attachments

        Issue Links

          Activity

            People

              sseifert Stefan Seifert
              ciechanowiec Herman Ciechanowiec
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: