Hey team, I want to share a binary incompatibilit...
# apollo-kotlin
g
Hey team, I want to share a binary incompatibility issue we run into recently. In case anyone experiences a similar problem (This is with Apollo v3) Here’s the learning: In the schema, order of optional fields in an Input type matter. If you change the order, it will change the order of fields in the generated code, which will change the order in the bytecode. If your schema module gets upgraded transitively you might get runtime errors. Even if you use named arguments. The cause: Generic types from Optional sealed class doesn’t have Java equivalent and the type is erased. At bytecode level, both OptionalString and OptionalBoolean are treated as Optional. When the order is modified, you end up with ClassCastException.
b
Ouch! Good one. I wonder if there's something we could do to mitigate this
m
Could
generateInputBuilders
help here?
b
ooh yes input objects builders should help! A previous discussion in this issue.
g
Yes that discussion was from me as well lol I should have mentioned this is with v3. Hopefully input builders in v4 will solve this (We still need to migrate to v4) This was interesting because it is actually not binary incompatible change.
japicmp
didn’t report this as binary breaking change which surprised me. After digging deeper I learned that, because of type erasure it is actually binary compatible 🤷 We are increasing the usage of
metalava
and my plan was to add it to the shared schema module for reporting purposes, and for versioning the generated types. However, this is not technically binary breaking change so it is an interesting one. (I wonder if
metalava
would have reported this as it has more Kotlin specific logic) For now, I think we will keep close eye on any changes to Input types in schema and don’t want to spend too much energy into this until we migrate to v4.
👍 1
b
I wonder if Kotlin BCV would have flagged the change
m
Signature of
fun foo(input: Optional<Int>)
is
Copy code
public static final fun toto (Lcom/apollographql/apollo3/api/Optional;)V
So BCV won’t do
b
all right - that makes sense
m
Copy code
method public static void foo(coffee.Optional<java.lang.Integer> bar);
Metalava would catch it though!
🎉 1