Hey all, coming across a very strange bug with a K...
# server
n
Hey all, coming across a very strange bug with a Kotlin data class that's being serialized to a JSON response using Jackson. I have a bool on the data class
isMyFeautureEnabled
and when the data class gets serialized, there are two booleans serailzed
isMyFeatureEnabled
and a phantom field
myFeatureEnabled
(without the is). If I change the name of
isMyFeatureEnabled
to something like
testFieldName
, then I don't see the phantom field. Anyone come across this before? So:
Copy code
data class MyData(
  val field1: String,
  val field2: String,
  val isMyFeautureEnabled: Boolean,
)

serializes to:

{
  "field1": "test",
  "field2": "test",
  "isMyFeatureEnabled": true,
  "myFeatureEnabled": true
}

but

data class MyData(
  val field1: String,
  val field2: String,
  val testField: Boolean,
)

serializes to:
{
  "field1": "test",
  "field2": "test",
  "testField": true
}
Not sure if it's a Kotlin thing or a Jackson thing but it must be something to do with the
is
in the name.
UPDATE: It was a Jackson thing, Jackson was trying to do some weird automagical stuff but putting an
@get:JsonProperty("isMyFeautreEnabled")
annotation on it fixed it.
d
This is Jackson being "helpful". Our solution to this type of thing has just been to use Moshi if possible 🙃
k
t
Yeah, this is a class Jackson IS GETTER. You can disable it in your mapper configuration without having to explicitly use a @JsonProperty annotation on the affected field: https://github.com/FasterXML/jackson-databind/wiki/Mapper-Features
d
The principle of most surprise strikes again! 😉
kodee surprised 1
d
Maybe the defaults make sense for Java?
d
I'm not really sure they do - at least for modern java. I suspect the decision comes from waaaaaay back when everyone was doing "java beans"
m
The naming pattern for a getter of a boolean property is defined as
is<PropertyName>
for java-beans as per specification (at least the last time I had a look at it). That is most possibly the reason for jackson to interpret the presence of a function like
is<PropertyName>
that returns
boolean
as if there was a boolean property with that particular name. Remember that kotlin autogenerates the function
isMyFeatureEnabled()
that returns a boolean for your val, that might be why jackson picks that up.
I'd suggest using kotlinx-serialization instead so you don't end up with java convention surprises like this 😄