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

Kotlin constructors using @ExperimentalUnsignedTypes parameters cause constructor resolution to fail [DATACMNS-1800] #2215

Closed
spring-projects-issues opened this issue Sep 19, 2020 · 3 comments

Comments

@spring-projects-issues
Copy link

@spring-projects-issues spring-projects-issues commented Sep 19, 2020

magneticflux- opened DATACMNS-1800 and commented

I have a Kotlin entity with a constructor that includes several defaulted parameters in no particular order. I also am using the Kotlin Spring and JPA Gradle plugins to generate default constructors for my entities.

Initializing a repository for my entity causes this crash:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRepository' defined in com.x.MyRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:624) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:612) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:51) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:36) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at com.x.ApplicationKt.main(Application.kt:153) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.4.RELEASE.jar:2.3.4.RELEASE]
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.buildPreferredConstructor(PreferredConstructorDiscoverer.java:215) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.access$200(PreferredConstructorDiscoverer.java:91) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers$2.lambda$discover$3(PreferredConstructorDiscoverer.java:171) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at java.base/java.util.Optional.orElseGet(Optional.java:369) ~[na:na]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers$2.discover(PreferredConstructorDiscoverer.java:160) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.discover(PreferredConstructorDiscoverer.java:79) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.BasicPersistentEntity.<init>(BasicPersistentEntity.java:105) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.mapping.JpaPersistentEntityImpl.<init>(JpaPersistentEntityImpl.java:59) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.createPersistentEntity(JpaMetamodelMappingContext.java:70) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.createPersistentEntity(JpaMetamodelMappingContext.java:44) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:372) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:263) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:206) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:90) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$4(RepositoryFactoryBeanSupport.java:295) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at java.base/java.util.Optional.ifPresent(Optional.java:183) ~[na:na]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:295) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	... 30 common frames omitted

Affects: 2.3.4 (Neumann SR4)

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Sep 21, 2020

Mark Paluch commented

Can you provide a reproducer or attach the offending entity class?

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Sep 27, 2020

magneticflux- commented

It stems from using Kotlin unsigned integer types and DATACMNS-1517. Unsigned types are implemented using inline classes, triggering the existing issue. Here's a reproduction of the issue:

package com.skaggsm.reproduction

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.data.jpa.repository.JpaRepository
import javax.persistence.Entity
import javax.persistence.Id

@SpringBootApplication
class ReproductionApplication

fun main(args: Array<String>) {
    runApplication<ReproductionApplication>(*args)
}

@ExperimentalUnsignedTypes
@Entity
data class ExampleEntity(
        @Id
        val id: String,
        val a: UInt = 5u,
        val b: Int = 5,
        val c: Double = 1.5
)

@ExperimentalUnsignedTypes
interface ExampleEntityRepository : JpaRepository<ExampleEntity, String>

@mp911de mp911de closed this in ce4558f Jan 18, 2021
mp911de added a commit that referenced this issue Jan 18, 2021
We now leniently skip parameter name resolution for types using unsigned types. The issue is caused by Kotlin's DefaultConstructorMarker that doesn't report a parameter name.

Closes #2215
mp911de added a commit that referenced this issue Jan 18, 2021
We now leniently skip parameter name resolution for types using unsigned types. The issue is caused by Kotlin's DefaultConstructorMarker that doesn't report a parameter name.

Closes #2215
@mp911de
Copy link
Member

@mp911de mp911de commented Jan 18, 2021

We can address the issue by guarding the parameter name lookup so the parameter name for DefaultConstructorMarker stays null. However, entity creation will still not work because the reflection method isn't aware that DefaultConstructorMarker should be skipped. Generated code isn't able to access DefaultConstructorMarker because the class is package-private although used in a public constructor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants