Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

constructor-impl of Kotlin value class is not called #32324

Closed
k163377 opened this issue Feb 24, 2024 · 5 comments
Closed

constructor-impl of Kotlin value class is not called #32324

k163377 opened this issue Feb 24, 2024 · 5 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: kotlin An issue related to Kotlin support type: bug A general bug
Milestone

Comments

@k163377
Copy link

k163377 commented Feb 24, 2024

The init block of the value class can contain processing.

@JvmInline
value class Value(val value: Int) {
    init {
        if (100 < value) throw IllegalArgumentException()
    }
}

This will be compiled into a method named constructor-impl in the bytecode.

When instantiating a value class using Java reflection, both constructor-impl and box-impl must be called in order to be equivalent to instantiating it on Kotlin.
On the other hand, there is no evidence that constructor-impl is called in the spring-framework, and only box-impl seems to be called.

Is this an intentional design?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 24, 2024
@sdeleuze sdeleuze added the theme: kotlin An issue related to Kotlin support label Feb 24, 2024
@sdeleuze sdeleuze self-assigned this Feb 24, 2024
@sdeleuze
Copy link
Contributor

I have reached Kotlin team to get related guidance.

@sdeleuze sdeleuze added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 27, 2024
@sdeleuze sdeleuze added this to the 6.1.5 milestone Feb 27, 2024
@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Feb 28, 2024
@efemoney
Copy link

efemoney commented Mar 1, 2024

Coroutine handling (in CoroutineUtils.invokeSuspendingFunction) calls box-impl directly. Ideally that would call the value class single primary constructor gotten from kotlin reflection.

@sdeleuze
Copy link
Contributor

sdeleuze commented Mar 1, 2024

@efemoney Unless I am mistaken, and as confirmed by the Kotlin team, this is not possible due to #31698.

@efemoney
Copy link

efemoney commented Mar 1, 2024

Yeah I saw that but its slightly different from what I am saying which is

value class PlanId(val value: Int) {
  init {
    require(value >= 0) // Throw if value is negative
  }
}

assertEquals(
  PlanId(21),
  PlanId::class.primaryConstructor!!.call(21),
)

assertFails {
  PlanId::class.primaryConstructor!!.call(-21)
}

The only issue is this will need to use kotlin reflection KClasses.getPrimaryConstructor(kClass).call(args[index]), I dont know if thats desired or not

@sdeleuze
Copy link
Contributor

sdeleuze commented Mar 1, 2024

Good point, should be ok to use this.

sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Mar 1, 2024
In order to invoke the init block and to improve the maintainability.

Closes spring-projectsgh-32324
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: kotlin An issue related to Kotlin support type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants