Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-15673

Kotlin class instantiation with optional parameters and default values

    Details

    • Last commented by a User:
      true

      Description

      Following the work done on SPR-15199, it seems we don't support currently Kotlin classes with default parameters since the bytecode generated contains 2 constructors.

      This comment from Jayson Minard provide useful guidance. We could maybe take inspiration of https://github.com/FasterXML/jackson-module-kotlin/ that implements similar support.

      This feature should if possible be reusable from Spring Boot for its support for @ConfigurationProperties and Spring Data which currently requires Kotlin noarg compiler plugin (I have validated it is currently required via MiXiT application, would be nice to be able to avoid using this plugin which is basicaly a trick for libraries without Kotlin support).

      Juergen Hoeller I am going to try to write Kotlin tests that demonstrate the issue and try to find the right Kotlin API to use for that, I may need your guidance for the steps after that.

        Issue Links

          Activity

          Hide
          sdeleuze Sébastien Deleuze added a comment - - edited

          For the record, Jayson Minard provided these hints to help us based on his experience on the Jackson Kotlin module:

          Jackson Kotlin Module looks for the Primary Constructor (if more than one) or the ONLY constructor (if only one).
          https://github.com/FasterXML/jackson-module-kotlin/blob/master/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt#L98

          It also ensures that all parameters have `name` attributes.
          Creation of object based on getting called back with a set of parameters is done at:
          https://github.com/FasterXML/jackson-module-kotlin/blob/master/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt

          Show
          sdeleuze Sébastien Deleuze added a comment - - edited For the record, Jayson Minard provided these hints to help us based on his experience on the Jackson Kotlin module: Jackson Kotlin Module looks for the Primary Constructor (if more than one) or the ONLY constructor (if only one). https://github.com/FasterXML/jackson-module-kotlin/blob/master/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt#L98 It also ensures that all parameters have `name` attributes. Creation of object based on getting called back with a set of parameters is done at: https://github.com/FasterXML/jackson-module-kotlin/blob/master/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt
          Hide
          sdeleuze Sébastien Deleuze added a comment -
          Show
          sdeleuze Sébastien Deleuze added a comment - Pull request submitted: https://github.com/spring-projects/spring-framework/pull/1482
          Hide
          mschulze Moritz Schulze added a comment -

          I would like to add that after the upgrade to Spring Boot 2.0.0 M3 this actually broke some Kotlin compability for me.

          I had a @ConfigurationProperties class with a constructor that had default values for all parameters. This worked fine in M2

          @ConfigurationProperties("foo")
          class FooProperties(
              var bar: String = "bar",
              var baz: Int = 1
          )
          

          With M3 I get

          Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.techdev.xyz.FooProperties]: No corresponding Kotlin constructor found
                  at org.springframework.beans.BeanUtils$KotlinDelegate.instantiateClass(BeanUtils.java:742) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
                  at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:165) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
                  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:88) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
          

          So I had to change to

          @ConfigurationProperties("foo")
          class FooProperties {
              var bar: String = "bar",
              var baz: Int = 1
          }
          

          (which of cause is not that big of a hassle - I didn't use the constructor anywhere manually anyway).

          Show
          mschulze Moritz Schulze added a comment - I would like to add that after the upgrade to Spring Boot 2.0.0 M3 this actually broke some Kotlin compability for me. I had a @ConfigurationProperties class with a constructor that had default values for all parameters. This worked fine in M2 @ConfigurationProperties("foo") class FooProperties( var bar: String = "bar", var baz: Int = 1 ) With M3 I get Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.techdev.xyz.FooProperties]: No corresponding Kotlin constructor found at org.springframework.beans.BeanUtils$KotlinDelegate.instantiateClass(BeanUtils.java:742) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3] at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:165) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:88) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3] So I had to change to @ConfigurationProperties("foo") class FooProperties { var bar: String = "bar", var baz: Int = 1 } (which of cause is not that big of a hassle - I didn't use the constructor anywhere manually anyway).
          Hide
          sdeleuze Sébastien Deleuze added a comment -

          Moritz Schulze Could you please create a dedicated issue describing this regression? I will have a look before RC4.

          Show
          sdeleuze Sébastien Deleuze added a comment - Moritz Schulze Could you please create a dedicated issue describing this regression? I will have a look before RC4.
          Hide
          mschulze Moritz Schulze added a comment -

          I guess this ticket for Spring Boot will fix this in the end: https://github.com/spring-projects/spring-boot/issues/8762, so maybe that is not necessary?

          Show
          mschulze Moritz Schulze added a comment - I guess this ticket for Spring Boot will fix this in the end: https://github.com/spring-projects/spring-boot/issues/8762 , so maybe that is not necessary?
          Hide
          sdeleuze Sébastien Deleuze added a comment -

          This is a regression reported already 2 times, so maybe there is something to improve. Please create an issue in order to make sure I have a look before RC4.

          Show
          sdeleuze Sébastien Deleuze added a comment - This is a regression reported already 2 times, so maybe there is something to improve. Please create an issue in order to make sure I have a look before RC4.
          Hide
          sdeleuze Sébastien Deleuze added a comment -

          SPR-15851 has been creted to track and fix this regression.

          Show
          sdeleuze Sébastien Deleuze added a comment - SPR-15851 has been creted to track and fix this regression.

            People

            • Assignee:
              sdeleuze Sébastien Deleuze
              Reporter:
              sdeleuze Sébastien Deleuze
              Last updater:
              Juergen Hoeller
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                15 weeks, 2 days ago