Problem:

With the below setup:

@FeignClient(name = "play-client", configuration = PlayClientConfiguration.class)
public interface PlayClient {

    @GetMapping("/play-value")
    PlayResponseValue playValue(@RequestParam String item);

    @lombok.Value
    class PlayResponseValue {
        String result;
    }
}

I'm getting the following exception:

Caused by: org.springframework.web.client.RestClientException: Error while extracting response for type [class com.playtika.services.samples.PlayClient$PlayResponseValue] and content type [application/json]
        at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:118)
        at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:75)
        at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:61)
        at feign.optionals.OptionalDecoder.decode(OptionalDecoder.java:36)
        at feign.InvocationContext.proceed(InvocationContext.java:36)
        ... 37 common frames omitted
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.playtika.services.samples.PlayClient$PlayResponseValue` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:406)
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:354)
        at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:103)
        ... 41 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.playtika.services.samples.PlayClient$PlayResponseValue` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2]
        at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1739)

But everything works perfectly when using a java application (non native).

Investigation results:

At first I thought this was a hint issue, but I checked and they were indeed automatically generated.

{
    "name": "com.playtika.services.samples.PlayClient$PlayResponseValue",
    "allDeclaredConstructors": true,
    "allDeclaredFields": true,
    "methods": [ { "name": "getResult", "parameterTypes": [ ] } ]
  }

I tried adding the constructor as a method hint manually, but that didn't help.

I also attempted to solve this by adding: lombok.anyConstructor.addConstructorProperties=true, which ensured that this was my class file:

public static final class PlayResponseValue {
        private final String result;

        @ConstructorProperties({"result"})
        @Generated
        public PlayResponseValue(final String result) {
            this.result = result;
        }

        @Generated
        public String getResult() {
            return this.result;
        }
...
}

but that didn't help.

Workarounds:

Everything works in either case: * if the DTO is reimplemented to be a java record. * when @lombok.RequiredArgsConstructor(onConstructor_={@JsonCreator}) is added to the dto

These workarounds are generally acceptable, although would require a lot of effort to implement across multiple services.

Since the constructor is present, the hint for it as well, I believe that native should be able to detect everything just as java would.

Comment From: wilkinsona

I don't think Spring Boot is likely to be the cause here. Please report this to the Spring Cloud OpenFeign project so that they can investigate.

Comment From: dpozinen

reopened in https://github.com/spring-cloud/spring-cloud-openfeign/issues/966