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

DokkaConfiguration: Use LinkedHashSet instead of Set to preserve order for includes when deserialize (#2999) #3006

Merged
merged 2 commits into from Jul 12, 2023

Conversation

eunwoop
Copy link
Contributor

@eunwoop eunwoop commented May 22, 2023

  • for markdown files for multi module description

@IgnatBeresnev
Copy link
Member

IgnatBeresnev commented May 23, 2023

Hi! Does it resolve #2999? It'll be surprised if it does, because I believe .toSet() already creates LinkedHashSet internally, so there should be no change in behavior between your proposal and the current implementation.

@eunwoop eunwoop changed the title [WIP] DokkaConfiguration: Use LinkedHashSet instead of Set to preserve order for includes (#2999) DokkaConfiguration: Use LinkedHashSet instead of Set to preserve order for includes (#2999) May 24, 2023
@eunwoop
Copy link
Contributor Author

eunwoop commented May 28, 2023

It’s because DokkaConfigurationImpl is serialized and then deserialized using JSON and the order is not preserved during that process.

When I print the log before serialization, the order of elements in the includes is preserved. However, after deserializing the JSON string and using a Set type for the includes field, the order is not preserved.
I guess Jackson does not guarantee the order of fields for Set types.
So when I changed the includes field's type to LinkedHashSet, it preserves the order of elements during deserialization.

The serialization and then deserialization happens here -->

In AbstractDokkaTask, the buildDokkaConfiguration() method returns a DokkaConfiguration object, and then toCompactJsonString() method is called to convert it into a JSON string.

    @TaskAction
    internal open fun generateDocumentation() {
        DokkaBootstrap(runtime, DokkaBootstrapImpl::class).apply {
            configure(buildDokkaConfiguration().toCompactJsonString(), createProxyLogger())

And then inside DokkaBootstrapImpl.configure(), the DokkaConfigurationImpl is created with the serialized JSON configuration.

    override fun configure(serializedConfigurationJSON: String, logger: BiConsumer<String, String>) = configure(
        DokkaProxyLogger(logger),
        DokkaConfigurationImpl(serializedConfigurationJSON) // HERE
    )

@IgnatBeresnev IgnatBeresnev self-requested a review May 30, 2023 20:26
@IgnatBeresnev
Copy link
Member

However, after deserializing the JSON string

Oh yeah, I completely forgot about it.. what a strange bug... Thanks for diving deep and researching it!

Using LinkedHashSet and breaking the Set abstraction kind of feels bad, and it'll be a breaking API change for some of the clients (since this is public API)..

Please, give me a few days to discuss this with my colleagues, maybe we can think of something. I'll try to get back to you on Friday

@eunwoop eunwoop changed the title DokkaConfiguration: Use LinkedHashSet instead of Set to preserve order for includes (#2999) DokkaConfiguration: Use LinkedHashSet instead of Set to preserve order for includes when deserialize (#2999) Jun 8, 2023
@eunwoop
Copy link
Contributor Author

eunwoop commented Jun 8, 2023

@IgnatBeresnev
Hello, I updated my change to avoid breaking API change.
Instead, I used addAbstractTypeMapping for objectMapper.

* for markdown files for multi module description
@eunwoo-park-nhn
Copy link
Contributor

@IgnatBeresnev Hello I updated the PR. Could you reveiw this?

@IgnatBeresnev
Copy link
Member

Hi! Yes, sorry for the delay and thank you for not giving up :)

Copy link
Member

@IgnatBeresnev IgnatBeresnev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat solution, and I think it makes sense!

If you have the time, could you please add a simple test to core/src/test/kotlin/utilities/JsonKtTest.kt for the parseJson function? Just to make sure it doesn't break in the future

@IgnatBeresnev
Copy link
Member

Thanks!

@IgnatBeresnev IgnatBeresnev merged commit 20e06e8 into Kotlin:master Jul 12, 2023
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants