spring-attic / spring-native

Spring Native is now superseded by Spring Boot 3 official native support
https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html
Apache License 2.0
2.74k stars 356 forks source link

Spring-Cloud discoveryclient sample possibly doesn't work #1720

Closed amizurov closed 1 year ago

amizurov commented 1 year ago

Hello folks, i'm trying to build a spring-boot native application with spring-cloud-starter-netflix-eureka-client integration but i got the exception on startup:

Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://localhost:8761/eureka/}, exception=Type definition error: [simple type, class com.netflix.discovery.shared.Application]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.netflix.discovery.shared.Application` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 81] (through reference chain: com.netflix.discovery.converters.jackson.builder.ApplicationsJacksonBuilder["application"]->java.util.ArrayList[0]) stacktrace=org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.netflix.discovery.shared.Application]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.netflix.discovery.shared.Application` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 81] (through reference chain: com.netflix.discovery.converters.jackson.builder.ApplicationsJacksonBuilder["application"]->java.util.ArrayList[0])
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:388)
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:343)
        at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:105)
        at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1037)
        at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1020)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:778)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
        at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:602)
        at org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient.getApplicationsInternal(RestTemplateEurekaHttpClient.java:145)
        at org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient.getApplications(RestTemplateEurekaHttpClient.java:135)
        at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)
        at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.executeOnNewServer(RedirectingEurekaHttpClient.java:121)
        at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.execute(RedirectingEurekaHttpClient.java:80)
        at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
        at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)
        at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:120)
        at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
        at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)
        at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77)
        at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
        at com.netflix.discovery.DiscoveryClient.getAndStoreFullRegistry(DiscoveryClient.java:1101)
        at com.netflix.discovery.DiscoveryClient.fetchRegistry(DiscoveryClient.java:1014)
        at com.netflix.discovery.DiscoveryClient.refreshRegistry(DiscoveryClient.java:1531)
        at com.netflix.discovery.DiscoveryClient$CacheRefreshThread.run(DiscoveryClient.java:1498)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
        at java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.lang.Thread.run(Thread.java:833)
        at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:705)
        at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.netflix.discovery.shared.Application` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 81] (through reference chain: com.netflix.discovery.converters.jackson.builder.ApplicationsJacksonBuilder["application"]->java.util.ArrayList[0])
        at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1904)
        at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
        at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1349)
        at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:351)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:184)
        at com.fasterxml.jackson.databind.dese^Cl.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3682)
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:380)
        ... 30 more

Reproducer: Build the sample application discoveryclient and run it.

After I manually added hints:

@SpringBootApplication
@EnableDiscoveryClient
@TypeHint(types = { Application.class, InstanceInfo.class, MyDataCenterInfo.class }, typeNames = {
        "com.netflix.discovery.shared.Application",
        "com.netflix.appinfo.InstanceInfo",
        "com.netflix.appinfo.InstanceInfo$PortWrapper",
        "com.netflix.appinfo.DataCenterInfo"
})
public class DiscoveryClientApplication {
...
}

everything worked. But if i understand correct all required hints already present in spring-native-configuration

Could you tell me if this is a bug or am I doing something wrong ?

sdeleuze commented 1 year ago

The trigger for the Spring Native related configuration is EurekaClientAutoConfiguration, maybe it is not enable in your application. Could you check if it is active by watching the report generated with --debug when running the app on the JVM?

amizurov commented 1 year ago

@sdeleuze Thanks for you reply. Just to clarify this is not a problem in my custom project it's also problem in sample. If you just up the eureka server without any application instance registered and run the native discoveryclient everything will work. But if you register any application instance (e.g. configserver or another app) and re-run discoveryclient it will fail with the issue which i'm described above. When a I add the following hints to the sample, it starts working

@TypeHint(types = { Application.class, InstanceInfo.class, MyDataCenterInfo.class }, typeNames = {
        "com.netflix.appinfo.InstanceInfo$PortWrapper",
})
sdeleuze commented 1 year ago

@OlgaMaciaszek Please make sure we support this use case with Spring Boot 3.

OlgaMaciaszek commented 1 year ago

Yes, I'm planning to start testing Eureka client integration today (we've only recently published the first Eureka Client 4.x milestone).

OlgaMaciaszek commented 1 year ago

It works fine on Spring Cloud 2022.x now. A PR with sample has been submitted. We're not planning to further work on Spring Native project.