-
Notifications
You must be signed in to change notification settings - Fork 174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serialization doesn't work correctly for objects parametrized by inline class #464
Comments
If the policy is to always https://github.com/k163377/jackson-module-kotlin/tree/github_464 |
Looks good, because for now I'm using custom serializer as a quick workaroud :) private class NodeIdSerializer : JsonSerializer<Collection<NodeId>>() {
override fun serialize(value: Collection<NodeId>, gen: JsonGenerator, serializers: SerializerProvider) {
return gen.writeArray(value.map(NodeId::value).toTypedArray(), 0, value.size)
}
} |
@k163377 I like the looks of those branch changes, does that break any other tests? |
@dinomite However, it seems to have the following problems.
As for 1, the same problem occurs when I also feel that there are hidden problems that I am not aware of... Additional ContextFound a problem with // works
@JvmInline
value class ValueByGetter(@get:JsonValue val value: Int)
// does not work
@JvmInline
value class ValueByMethod(val value: Int) {
@JsonValue
fun jsonValue() = value.toString()
} This is due to the fact that this method is compiled into a @JsonValue
@NotNull
public static final String jsonValue_impl/* $FF was: jsonValue-impl*/(int $this) {
return String.valueOf($this);
} Due to this problem, setting |
Value classes will ultimately support multiple fields and compile to primitive classes on the JVM, when they are introduced. Value classes with multiple fields will not support @JvmInline, so ideally we should check for that annotation before auto-unboxing to avoid backward compatibility issues. |
@Quantum64
I read this as "After type.rawClass.let { clazz -> clazz.annotations.any { it is JvmInline } && clazz.isKotlinClass() } ->
ValueClassUnboxSerializer However, I could not read from this document that Am I understanding you correctly so far? Or am I misreading your comments? |
Yes, I agree with everything you said. After reading a second time, I agree that the language in the specification is not clear enough to completely rule out @JvmInline classes with multiple fields, so I asked the question in the Kotlin Slack channel. We will see if anyone from JetBrains gets back to me. |
@Quantum64 If this pattern were to be strictly avoided, it would seem that the number of |
I haven't heard back from JB yet but someone else brought up a good point. It would be impossible to use a @JvmInline class with multiple fields as a return type because the fields could not be inlined into the single return type required by the JVM. I think based on this, it is safe to assume that @JvmInline classes will only ever have one field. |
With the merging of #468, value classes should work except as |
@dinomite Can you get snapshots to deploy with |
@cowtowncoder I cannot, I don't have access to the Jackson Sonatype repo |
@dinomite could you file an issue at https://issues.sonatype.org/ for type OSSRH ? Or actually I could do it, if you could create an account at that Jira tracker (just so I can at-reference you). It should be possible to grant you access just to Kotlin module, I think; same was done wrt Scala module. |
Ah. Here's the request for Scala module: https://issues.sonatype.org/browse/OSSRH-51205 which would be the way to do it. I think that the account for Sonatype Jira also works for their Nexus, which is why this should work quite fine. I just need to ok your request. |
@dinomite Thanks! |
@dinomite Before the #468 merge, the following three situations will output values that are not
Verification codeimport com.fasterxml.jackson.annotation.JsonPropertyOrder
import com.fasterxml.jackson.databind.ObjectWriter
import org.junit.Test
class Github464AdditionalTests {
interface IValue
@JvmInline
value class ValueClass(val value: Int) : IValue
abstract class AbstractGetter<T> {
abstract val byAbstractGenericVal: T
fun <T> getByAbstractGenericFun() = byAbstractGenericVal
}
interface IGetter<T> {
val byInterfaceGenericVal: T
fun <T> getByInterfaceGenericDefaultFun() = byInterfaceGenericVal
}
@JsonPropertyOrder(alphabetic = true)
data class BoxedFields(
val asInterface: IValue,
override val byAbstractGenericVal: ValueClass,
override val byInterfaceGenericVal: ValueClass,
val nullableValue: ValueClass?
) : AbstractGetter<ValueClass>(), IGetter<ValueClass> {
constructor(value: ValueClass) : this(value, value, value, value)
}
@Test
fun test() {
val target = BoxedFields(ValueClass(1))
val writer: ObjectWriter = jacksonObjectMapper()
.writerWithDefaultPrettyPrinter()
println(writer.writeValueAsString(target))
}
}
{
"asInterface" : {
"value" : 1
},
"byAbstractGenericFun" : {
"value" : 1
},
"byAbstractGenericVal" : 1,
"byInterfaceGenericDefaultFun" : 1,
"byInterfaceGenericVal" : 1,
"nullableValue" : {
"value" : 1
}
} The following materials were used as a reference. The change in #468 will also output Also, with the future update of |
@k163377 Sorry for the delays in getting back to this and the related PRs—I intend to pick this up in the next few weeks. |
Merged #470. |
A new snapshot build is up |
I have created it and would appreciate your review. |
I think merge to |
@cowtowncoder Sorry I hadn't fixed those in the |
np! |
Output:
Jackson version 2.12
The text was updated successfully, but these errors were encountered: