I am building two microservices which are supposed to talk to each other. I am using Eureka as service registry.

Microservice 1 - Microservice1.java

    @SpringBootApplication
    public class Microservice1Application {
        public static void main(String[] args) {
            SpringApplication.run(Microservice1Application.class, args);
        }
    }

Microservice1Controller.java

    @RestController
    @RequestMapping("/getdata")
    public class Microservice1Controller {  
        @GetMapping(value = "/") 
    public ResponseEntity<Microservice1ResponseWrapper<List<Customer1>>> getAll() {
            List<Customer1> list = //get data from repository

            return new ResponseEntity<Microservice1ResponseWrapper<List<Customer1>>>(new Microservice1ResponseWrapper<List<Customer1>>(Microservice1ResponseStatus.SUCCESS,list);
        }
    }

Microservice1ResponseWrapper.java - this is generic wrapper

    public class Microservice1ResponseWrapper<T> {
    private Microservice1ResponseStatus status;
    private T data;
    //constructor, getter and setters
    }

applicationProperties.yaml

spring:
  application:
    name: microservice1

server:
  port: 8073
    public class Customer1 implements Serializable {

        private static final long serialVersionUID = 1L;

        private Long custId;

        private String custName;

        private String firstName;

        private String lastName;

        private Long age;

        public Customer1() {
        }

    //getter, setter and toString
    }

Microservice2 Microservice2 that will get data from Microservice1

    @SpringBootApplication
    public class Microservice2Application {
        public static void main(String[] args) {
            SpringApplication.run(Microservice2Application.class, args);
        }
    }

    @Configuration
    class Config {

        @LoadBalanced
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }

Microservice2Controller.java

    @RestController
    @RequestMapping("/fetchdata")
    public class Microservice2Controller {  
    @Autowired
        private RestTemplate restTemplate;


        @GetMapping(value = "/")
    public ResponseEntity<Microservice2ResponseWrapper<List<Customer2>>> getAll() {     
                String getAllUrl = "http://microservice1/getdata/";
                ParameterizedTypeReference<Microservice2ResponseWrapper<List<Customer2>>>  parameterizedTypeReference = 
                        new ParameterizedTypeReference<Microservice2ResponseWrapper<List<Customer2>>>(){};

                ResponseEntity<Microservice2ResponseWrapper<List<Customer2>>> listData =
                        restTemplate.exchange(getAllUrl, HttpMethod.GET, null,parameterizedTypeReference);          
                return listData;
        }   
    }

Microservice2ResponseWrapper.java - this is generic wrapper

    public class Microservice2ResponseWrapper<T> {
    private Microservice2ResponseStatus status;
    private T data;
    //constructor, getter and setters
    }

applicationProperties.yaml

spring:
  application:
    name: microservice2

server:
  port: 8074

Customer1(in Microservice1) and Customer2(Microservice2) are almost identical objects.

Customer2.java in Microservice2

    public class Customer2 implements Serializable {

        private static final long serialVersionUID = 1L;

        private Long custId;

        private String custName;

        private String firstName;

        private String lastName;

        private Long age;

        public Customer2() {
        }

    //getter, setter and toString
    }

When I run Microservice1 : http://localhost:8073/getdata it gets data from database and works fine. Here is the response I see on screen:

    <Microservice1ResponseWrapper>
    <status>SUCCESS</status>
    <data>
    <custId>1</custId>
    <custName>string1</custName>
    <firstName>string1</firstName>
    <lastName>string1</lastName>
    <age>30</age>
    </data>
    </Microservice1ResponseWrapper>

When I run Microservice2 : http://localhost:8074/fetchdata it should go to Microservice 1 and get data.

However, I am getting error like:

org.springframework.web.client.RestClientException: Error while extracting response for type
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:117)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:994)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:977)

Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.rest.Customer2` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.rest.Customer2` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1')
 at [Source: (PushbackInputStream); line: 1, column: 61] (through reference chain: com.rest.wrapper.Microservice2ResponseWrapper["data"]->java.util.ArrayList[0])
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:245)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:227)
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:102)
    ... 77 more

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.rest.Customer2` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1')
 at [Source: (PushbackInputStream); line: 1, column: 61] (through reference chain: com.rest.wrapper.Microservice2ResponseWrapper["data"]->java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032)
    at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371)
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1373)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:171)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3084)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:239)

If I make following change in Microservice2 Controller then I see 2 issues: 1) start getting LinkedHashMap error. java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to java.util.List 2) It doesn't pull all records, it just pulls last element from List. e.g. There are 2 users, then it just shows last one user and not all.

ParameterizedTypeReference<Microservice2ResponseWrapper>  parameterizedTypeReference = 
                        new ParameterizedTypeReference<Microservice2ResponseWrapper>(){};

ResponseEntity<Microservice2ResponseWrapper> listData =
                        restTemplate.exchange(getAllUrl, HttpMethod.GET, null,parameterizedTypeReference);
List ls = (List) listData.getBody().getData();

//if I print listData.getBody().getData() then it just shows only one record of users.

Am I making any mistake in ParameterizedTypeReference or resttemplate exchange call?

NOTE: If I run these two microservices without Eureka registry, they work absolutely fine. But the moment I introduce Eureka and register these two services with Eureka, I get issue as stated above. For this I just made the change to Miroservice2 controller: String getAllUrl = "http://localhost:8073/getdata/";

Comment From: jamesfernando94

Also had this or a similar issue when trying to use restTemplate.exchange() inside of a generic method

Comment From: rstoyanchev

Am I making any mistake in ParameterizedTypeReference or resttemplate exchange call?

I don't think so.

If I run these two microservices without Eureka registry, they work absolutely fine.

This isn't anything we can fix in the Spring Framework then.

If you do decide to open an issue against Spring Cloud (e.g. spring-cloud-netflix), I would advise that you provide an actual sample instead of a long description that in the end likely still requires putting together a sample in order to debug it. I would also suggest going a little further to try and narrow the issue. For example what are the actual request details that go out from service 2 to service 1 and what is the actual response, with and without Eureka. This might even help you to figure out the issue.