We use Google Guice for DI (mostly with constructor injection) and Jackson for object serialization to/from JSON. As such we build our object graph through Guice Modules.
How do we provide/instruct Jackson to use our pre-built Guice Injector? Or it's own injector based on a Guice Module we provide? My preference is to provide it the injector because we already have means to control which module is used based on the environment/configuration we want to run in.
Here's a unit test:
public class Building {
@JsonIgnore
public final ElectricalProvider electricalProvider;
public String name;
@Inject
Building(ElectricalProvider electricalProvider){
this.electricalProvider = electricalProvider;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
public interface ElectricalProvider {}
public class SolarElectricalProvider implements ElectricalProvider{}
@Test
public void testJacksonGuice() throws IOException {
Injector injector = Guice.createInjector(new Module() {
@Override public void configure(Binder binder) {
binder.bind(ElectricalProvider.class).to(SolarElectricalProvider.class);
}
});
Building building1 = injector.getInstance(Building.class);
building1.setName("test building");
ObjectMapper objectMapper = new ObjectMapper();
byte[] buildingJsonBytes = objectMapper.writeValueAsBytes(building1);
Building building2 = objectMapper.readValue(buildingJsonBytes, Building.class);
assertThat(building1, is(equalTo(building2)));
assertThat(building2.electricalProvider, is(instanceOf(SolarElectricalProvider.class)));
}
That when run generates this exception com.fasterxml.jackson.databind.JsonMappingException
, with this message: No suitable constructor found for type [simple type, class Building]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
After a bit of googling, I came across the jackson-module-guice project but it doesn't appear to be what we need or doesn't provide as to how to accomplish what we need to do.