Skip to content
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

Clarification of how kotlinx.serialization handles versioning - Does it use semver? What are the minor/patch version guarantees? #2585

Closed
carstenhag opened this issue Mar 1, 2024 · 3 comments
Labels

Comments

@carstenhag
Copy link

The change #2530 that got included in 1.6.3 changed the behavior of kotlinx.serialization, leading to an exception in our app. I always try to read the release notes of the dependencies while upgrading. (In an ideal world, we would have tests for everything, and this wouldn't be necessary :D)

In this case, the change was summarized under "Bugfixes and improvements" as "Do not try to coerce input values for properties". Seemed pretty generic to me, so I didn't look into the code change.
Now a week later I see that in a special case we can receive values for an enum that we didn't expect. The behavior here seemed to be changed in a non-backwards compatible way and the app simply crashes. I don't want to go into details of how to solve that etc here, as that's not my question.

So, to my point: How does the library handle versioning? Is semver used?
In my opinion it was unexpected to have a breaking change listed as improvement, especially as it's not backwards compatible. Also, at a change from 1.6.2 to 1.6.3 according to semver there could only be backwards compatible bugfixes (no new features allowed).
After that, I guess that semver is not used? How can I make sure as a library user that this doesn't happen again?

@sandwwraith
Copy link
Member

sandwwraith commented Mar 4, 2024

First, I'll answer the generic question about versioning: No, it is not semver in its traditional definition. Generally, kotlinx libraries use versioning similar to Kotlin's with feature and incremental releases (https://kotlinlang.org/docs/releases.html). We also follow Kotlin's compatibility policy (https://kotlinlang.org/docs/kotlin-evolution.html#libraries) and our own (https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/compatibility.md#stable-api) which states that stable API shouldn't have backward-incompatible changes. So, a question about versions is a bit irrelevant: no matter which version you upgrade, stable API should be the same (modulo deprecations).

Regarding your particular issue, #2586: as I explained in detail there, such behavior was unspecified and implementation-defined. While we try to maintain the status quo with such cases, it doesn't mean that they are guaranteed to work forever (contrary to documented and tested parts that we cannot change), as implementation can change because of related (like #2530) or unrelated things. I understand your disappointment, and if I were aware of such a use case, I would try to maintain it while delivering the same bug fix.
I hope this answers your questions.

@carstenhag
Copy link
Author

Thanks a lot for the answer! It would be great for the release notes to contain possibly breaking changes, when it goes from unspecified to specified, but I am aware of this not always being possible (you can't know of something if you don't know it).

@carstenhag
Copy link
Author

Referencing here the comment from @dennisbellmann

#2586 (comment)

We in our project highly relied on the combination of
coerceInputValues=true and explicitNulls=false and I found it rather intuitive, that it also includes enums.
That's not the case anymore and it feels that i know have to read the documentation more carefully than ever.
Also a problem is, that this "feature" went away in a bugfix. If we would not have had a Unittest for this case, we would knew it too late.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants