[ 
https://issues.apache.org/jira/browse/SLING-12359?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Herman Ciechanowiec updated SLING-12359:
----------------------------------------
    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`:


{code:java}
@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;
    }
}
{code}


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:


{code:java}
@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) {}
{code}


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.

  was:
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`:


{code:java}
@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;     }

}
{code}


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:


{code:java}
@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) {}
{code}


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.


> Extend records support
> ----------------------
>
>                 Key: SLING-12359
>                 URL: https://issues.apache.org/jira/browse/SLING-12359
>             Project: Sling
>          Issue Type: Improvement
>          Components: Sling Models
>    Affects Versions: Models Implementation 1.6.4
>            Reporter: Herman Ciechanowiec
>            Priority: Blocker
>             Fix For: Models Implementation 1.6.6
>
>
> 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`:
> {code:java}
> @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;
>     }
> }
> {code}
> 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:
> {code:java}
> @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) {}
> {code}
> 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.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to