GuiceInjectableValues doesn't seem to work correctly
Opened this issue · 2 comments
Looking at the code of GuiceInjectableValues, it seems unable to handle string values, which is what you get by default:
@Override
public Object findInjectableValue(
Object valueId, DeserializationContext ctxt, BeanProperty forProperty, Object beanInstance
)
{
return injector.getInstance((Key<?>) valueId);
}
We try to deserialize an object of class A:
package org.example;
import com.fasterxml.jackson.annotation.*;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
public class A
{
private final String name;
@Inject
@JsonCreator
A(@JacksonInject X x, @Assisted @JsonProperty("name") String name) {
this.name = name;
}
public String getName() {
return name;
}
}
But valueId, in findInjectableValue, takes the name of the class, which is a string and cannot be converted to a Key, and we get an ClassCastException.
We ended-up creating our own InjectableValues subclass to handle this correctly:
package org.example;
import com.fasterxml.jackson.databind.*;
import com.google.inject.*;
public class WorkingGuiceInjectableValues extends InjectableValues
{
private final Injector injector;
public WorkingGuiceInjectableValues(Injector injector) {
this.injector = injector;
}
public Object findInjectableValue(Object valueId, DeserializationContext ctxt, BeanProperty forProperty, Object beanInstance) {
try
{
return this.injector.getInstance(WorkingGuiceInjectableValues.class.getClassLoader().loadClass((String)valueId));
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
}
This is what the main of our small toy program looks like:
package org.example;
import java.io.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.module.guice.*;
import com.google.inject.Guice;
public class Main
{
public static void main(String[] args) throws IOException
{
System.err.println("hello world");
var objectMapper = new ObjectMapper();
var injector = Guice.createInjector(new ObjectMapperModule(), new InjectionModule());
var aFactory = injector.getInstance(AFactory.class);
var a = aFactory.create("New instance of org.example.A !!!");
System.err.println("a name: " + a.getName());
var file = new File("a.json");
objectMapper.writer().writeValue(file, a);
var a2 = objectMapper.reader(new GuiceInjectableValues(injector)).readValue(file, A.class);
System.err.println("a2 name: " + a2.getName());
}
}
Version of guice: 5.1.0
Version of jackson-module-guice: 2.13.3
Program is available on GitHub: https://github.com/plcarmel/jackson-test
I don't know if the original author of this module is around any more, but if you were able to provide a PR against 2.14
I could merge improvements. I don't know how practical this would be wrt compatibility but if you think it is doable I always try to help get PRs merged.