Cuando usa jackson para mapear desde una cadena a su clase concreta, especialmente si trabaja con tipo genérico. entonces este problema puede ocurrir debido a un cargador de clases diferente. Lo conocí una vez con el siguiente escenario:
El proyecto B depende de la biblioteca A
en la biblioteca A:
public class DocSearchResponse<T> {
private T data;
}
tiene servicio para consultar datos de una fuente externa y usa jackson para convertir a una clase concreta
public class ServiceA<T>{
@Autowired
private ObjectMapper mapper;
@Autowired
private ClientDocSearch searchClient;
public DocSearchResponse<T> query(Criteria criteria){
String resultInString = searchClient.search(criteria);
return convertJson(resultInString)
}
}
public DocSearchResponse<T> convertJson(String result){
return mapper.readValue(result, new TypeReference<DocSearchResponse<T>>() {});
}
}
en el Proyecto B:
public class Account{
private String name;
}
y uso ServiceA de la biblioteca para realizar consultas y también convertir datos
public class ServiceAImpl extends ServiceA<Account> {
}
y hacer uso de eso
public class MakingAccountService {
@Autowired
private ServiceA service;
public void execute(Criteria criteria){
DocSearchResponse<Account> result = service.query(criteria);
Account acc = result.getData();
}
}
sucede porque desde el cargador de clases de LibraryA, jackson no puede cargar la clase de cuenta, luego simplemente anula el método convertJson
en el proyecto B para dejar que jackson haga su trabajo
public class ServiceAImpl extends ServiceA<Account> {
@Override
public DocSearchResponse<T> convertJson(String result){
return mapper.readValue(result, new TypeReference<DocSearchResponse<T>>() {});
}
}
}