This is Jackson 2.3.3. I have recently learned about mixin annotations in Jackson am I'm trying to apply it to a class. Without success so far however. The class in question is a static class into another class:
public static class Report
{
// Some non relevant public static final fields, then:
public final int totalRuns;
public final int totalInvocations;
public final int totalMatches;
public final int totalMismatches;
public final double matchShare;
public final int reinvocations;
public final int rematches;
public final int remismatches;
public final double reinvocationShare;
public final long totalNanoTime;
public final List<RuleReport> ruleReports;
public Report(final int totalRuns, final int totalMatches,
final int totalMismatches, final int rematches,
final int remismatches, final long totalNanoTime,
final List<RuleReport> ruleReports)
{
this.totalRuns = totalRuns;
this.totalInvocations = totalMatches + totalMismatches;
this.totalMatches = totalMatches;
this.totalMismatches = totalMismatches;
this.matchShare = (double) totalMatches / (double) totalInvocations;
this.reinvocations = rematches + remismatches;
this.rematches = rematches;
this.remismatches = remismatches;
this.reinvocationShare = (double) reinvocations
/ (double) totalInvocations;
this.totalNanoTime = totalNanoTime;
this.ruleReports = ruleReports;
}
// Other, non relevant methods
}
And there are no other constructors. Therefore I wrote my mixin class as such:
public abstract class ProfilingReportMixin
{
@JsonProperty("runs")
private int totalRuns;
@JsonIgnore
private int totalInvocations;
@JsonProperty("matches")
private int totalMatches;
@JsonProperty("mismatches")
private int totalMismatches;
@JsonIgnore
private double matchShare;
@JsonIgnore
private int reinvocations;
@JsonProperty("rematches")
private int rematches;
@JsonProperty("remismatches")
private int remismatches;
@JsonIgnore
private double reinvocationShare;
@JsonIgnore
private long totalNanoTime;
@JsonProperty("ruleReports")
private List<RuleReport> ruleReports;
@JsonCreator
protected ProfilingReportMixin(
@JsonProperty("runs") final int totalRuns,
@JsonProperty("matches") final int totalMatches,
@JsonProperty("mismatches") final int totalMismatches,
@JsonProperty("rematches") final int rematches,
@JsonProperty("remismatches") final int remismatches,
@JsonProperty("totalNanoTime") final int totalNanoTime,
@JsonProperty("ruleReports") final List<RuleReport> ruleReports
)
{
}
}
Since there is no "bean constructor" I decided to go the @JsonCreator
way, obviously.
I create the Module
, register it, no problem... Except that it fails when attempting to deserialize a sample JSON:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class org.parboiled.parserunners.ProfilingParseRunner$Report]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: java.io.BufferedInputStream@b41b571; line: 2, column: 5]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1078)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:268)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2993)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2144)
at com.github.parboiled1.grappa.assertions.mixins.ProfilingReportMixin.main(ProfilingReportMixin.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
I don't really understand; I did annotate the mixin class' constructor with @JsonCreator
and it has always worked for me so far for "normal" deserialization (it is my first time trying a mixin).
Is this a bug in Jackson or am I doing something wrong?
edit: the main
:
public static void main(final String... args)
throws IOException
{
final ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
mapper.registerModule(GrappaModule.INSTANCE);
final Closer closer = Closer.create();
final InputStream in;
try {
in = closer.register(ProfilingReportMixin.class.
getResourceAsStream("/profilingReports/test.json"));
if (in == null)
throw new IOException("resource not found");
final ProfilingParseRunner.Report report
= mapper.readValue(in, ProfilingParseRunner.Report.class);
mapper.writerWithDefaultPrettyPrinter()
.writeValue(System.out, report);
} finally {
closer.close();
}
}
and the Module
:
public final class GrappaModule
extends SimpleModule
{
private static final Version VERSION = new Version(1, 0, 0,
"beta.5-SNAPSHOT", "com.github.parboiled1", "grappa");
public static final Module INSTANCE = new GrappaModule();
private GrappaModule()
{
super("grappa", VERSION);
}
@Override
public void setupModule(final SetupContext context)
{
context.setMixInAnnotations(ProfilingParseRunner.RuleReport.class,
RuleReportMixin.class);
context.setMixInAnnotations(ProfilingParseRunner.Report.class,
ProfilingReportMixin.class);
}
}