spring-projects / spring-data-commons

Spring Data Commons. Interfaces and code shared between the various datastore specific implementations.
https://spring.io/projects/spring-data
Apache License 2.0
771 stars 671 forks source link

@EnableSpringDataWebSupport not working in native image #3117

Closed czp3009 closed 1 month ago

czp3009 commented 3 months ago

With @EnableSpringDataWebSupport in graalvm native image, requests will always return 500

Consider following code:

@EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO)
@SpringBootApplication
class Application

@RestController
class DefaultController {
    @GetMapping("/")
    fun endpoint() = PageImpl(listOf(1, 2))
}

response:

{"timestamp":"2024-07-01T09:06:31.252+00:00","status":500,"error":"Internal Server Error","path":"/"}

log:

2024-07-01T09:06:31.220Z  WARN 1 --- [nio-8080-exec-1] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson serialization for type [class org.springframework.data.domain.PageImpl]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.web.config.SpringDataJacksonConfiguration$PageModule$PageModelConverter': Failed to instantiate [org.springframework.data.web.config.SpringDataJacksonConfiguration$PageModule$PageModelConverter]: No default constructor found

issue reproduction repository: https://github.com/czp3009/spring-EnableSpringDataWebSupport-not-working-in-native-image

please follow the steps in the repository README to reproduce

========================================================= More discoveries: there is the same result whether pageSerializationMode is specified or not. log of another case:

2024-07-01T09:24:55.564Z  WARN 1 --- [nio-8080-exec-1] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson serialization for type [class org.springframework.data.domain.PageImpl]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.web.config.SpringDataJacksonConfiguration$PageModule$PlainPageSerializationWarning': Failed to instantiate [org.springframework.data.web.config.SpringDataJacksonConfiguration$PageModule$PlainPageSerializationWarning]: No default constructor found
2024-07-01T09:24:55.595Z  WARN 1 --- [nio-8080-exec-1] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson serialization for type [class org.springframework.data.domain.PageImpl]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.web.config.SpringDataJacksonConfiguration$PageModule$PlainPageSerializationWarning': Failed to instantiate [org.springframework.data.web.config.SpringDataJacksonConfiguration$PageModule$PlainPageSerializationWarning]: No default constructor found
2024-07-01T09:24:55.596Z  WARN 1 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.UnsupportedOperationException)]
czp3009 commented 3 months ago

workaround for someone else also meet this problem:

class SpringDataJacksonHints: RuntimeHintsRegistrar {
    override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
        hints.reflection().registerType(TypeReference.of(
            "org.springframework.data.web.config.SpringDataJacksonConfiguration\$PageModule\$PageModelConverter"
        ), MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
        hints.reflection().registerType(TypeReference.of(
            "org.springframework.data.web.config.SpringDataJacksonConfiguration\$PageModule\$PlainPageSerializationWarning"
        ), MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
    }
}
christophstrobl commented 3 months ago

Thank you @czp3009 for raising the issue and the reproducer.