jackson-module-scala
jackson-module-scala copied to clipboard
"get" appearing in property names with 2.6.x
Filed from discussion with @christophercurrie in #217.
Here's a possible pattern (not 100% sure). I think using @JsonProperty without a value is causing this. I've confirmed that the issue goes away when I don't register the Scala module.
I'm building JSON for a class named Product. @JsonAutoDetect is set up on Surface so nothing is autodetected so I have to whitelist properties with @JsonProperty.
@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE,
fieldVisibility = JsonAutoDetect.Visibility.NONE,
getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE,
setterVisibility = JsonAutoDetect.Visibility.NONE)
public interface Surface { ... }
public abstract class AbstractSurface implements Surface { ... }
public class Product extends AbstractSurface implements Comparable<Product> { ... }
Some of my properties come from AbstractSurface and other come from Product, but I think that the ones that have the unexpected get prefix have @JsonProperty without a value.
Sorry, no test case right now but hopefully that points you in the right direction.
Thanks for the report. I have a good idea what might be causing it, but not sure how hard it will be to fix. I'll see what I can do.
@wuservices Can you tell me what I might have done wrong attempting to reproduce this? My test cases pass. See: https://github.com/FasterXML/jackson-module-scala/pull/237
@nbauernfeind Thanks for trying to pinpoint this. For my similar structure, my member variables are protected in the middle class in the hierarchy (JavaAFieldVisibility) and private for the equivalent of JavaFieldVisibility. Also, I have getters for each member and I put @JsonProperty on the getters. Hopefully adding getters will be enough to repro the issue and if not, maybe visibility will change behavior too.
Is there any update on this issue? I've inherited a large code base that's filled with Java beans being serialized into JSON using Jackson. These beans are filled with @JsonProperty annotations that have no values. I'm trying to introduce Scala into the code base, but am being held up by this issue.
Here's an example of the problem:
public class Point {
@JsonProperty
private Integer x;
@JsonProperty
private Integer y;
@JsonProperty
public Integer getX() {
return x;
}
@JsonProperty
public void setX(Integer x) {
this.x = x;
}
@JsonProperty
public Integer getY() {
return y;
}
@JsonProperty
public void setY(Integer y) {
this.y = y;
}
}
When I write this out using an ObjectMapper that has DefaultScalaModule registered on it, the resulting JSON is
{"x":5,"y":6,"getX":5,"getY":6}
If I don't register DefaultScalaModule, the resulting JSON is
{"x":5,"y":6}
The fix is in BeanIntrospector.scala. If you look at the following line near the bottom of the file
setter = findSetter(cls, name) if setter.isDefined || getter.getAnnotation(classOf[JsonProperty]) != null
I think you need to not just check if the annotation isn't null but also check to make sure it's value isn't an empty string. When I make that change locally, everything works correctly.
I'm on version 2.7.7 of the jackson scala module. I'm locked into 2.7 of the Jackson stuff because of dropwizard 1.0.
@nbauernfeind Do you think suggested fix makes sense? Could perhaps make it in 2.7.8, before it gets released.
I'm using 2.8.2 and seeing this issue, as well.
we're using 2.11.4 and seeing this issue as well with a java class only has @JsonProperty on getter. Unfortunately it's a provided class that we can't change.
A test case below can reproduce this issue:
class JacksonTest extends FunSuite {
test("Jackson") {
val mapper = new ObjectMapper()
mapper.findAndRegisterModules() // remove this to not register the scala modules can pass the test
val json = """{"v": 1}""".stripMargin
val token = mapper.readValue(json, classOf[Sample1])
assert(token.getValue == 1)
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
class Sample1 {
private var value: Int = 0
@JsonProperty("v") def getValue: Int = value
def setValue(value: Int): Unit = {this.value = value}
}
@keshin could you try upgrading to v2.12.x? https://github.com/FasterXML/jackson-module-scala/issues/455 might help you.
@pjfanning , thanks, does 2.12.X compatible with jackson-core 2.11.X? it might be challenge for us to upgrade all version to 2.12.X for jackson, want to see if I can upgrade scala module only
We're on spring boot 2.4.6, where the managed version for jackson is 2.11.4
no - jackson-module-scala is designed to be used with jackson core of the same version - looks like spring boot 2.5.2 uses jackson 2.12.3
@keshin your use case works if you move the @JsonProperty("v") to the setValue - you have to be aware that deserialization means that you need to set the values.
This also works
@JsonProperty("v") private var value: Int = 0
@pjfanning, it's a provided class, I agree it's not a good one but I can't change it. I tried to upgrade all jackson to 2.12.3 for my app (running with spring boot 2.4.6), everything looks good so far.