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

Consider enabling serialization plugin by default in Kotlin distribution #2797

Open
qwwdfsad opened this issue Aug 28, 2024 · 8 comments
Open

Comments

@qwwdfsad
Copy link
Member

Currently, kotlinx.serialization requires two components to function -- applied serialization plugin and the runtime JAR added to dependencies.

For newcomers, steepness of the general learning curve and build configuration, two-step procedure seems excessive (moreover, the overall plugin is rather an "implementation detail"), and we much likely can avoid that.

The serialization plugin is already bundled into Kotlin distribution, is released along with Kotlin and is, basically, part of the Kotlin.

I propose enabling it by default for all Kotlin project:

  • For projects without kotlinx-serialization-core in dependencies, the plugin will do nothing and won't contribute to the overall build correctness and performance
  • For projects with serialization in dependencies, it will keep working as is -- looking for the @Serializable annotation by FQN (and other annotations from kotlinx.* package) and transform classes accordingly

Effectively, it won't change the overall build pipelines, but will allow us to get rid of an extra configuration step

@pdvrieze
Copy link
Contributor

Interesting idea, but a precedent setting one. It almost screams for having something in the metadata of packages to allow automatic (compiler) plugin application. At the same time your rationale is valid (it is more a question whether it is worth the costs)

@recursive-rat4
Copy link
Contributor

I think consistency among plugins makes sense. Atomicfu has a similar question opened Kotlin/kotlinx-atomicfu#410

@qwwdfsad
Copy link
Member Author

qwwdfsad commented Aug 29, 2024

It almost screams for having something in the metadata of packages to allow automatic (compiler) plugin applications.

This one we rather generally prohibit. Having an implicitly-enabled compiler plugin from arbitrary dependencies (esp. taking into account that there are no compiler plugin APIs at all) is unlikely to be obvious, stable or healthy for an arbitrary user project. An attack vector as well, probably.

Serialization here is in privileged position, as it is de facto the Kotlin serialization that we control, and, had we picked a slightly different turn, would've been part of the Kotlin default distribution.

it is more a question whether it is worth the costs

My proposal only makes sense if the costs (for end users in terms of their build performance and stability; our maintenance cost is kind of out of question here) are negligible

@xiaozhikang0916
Copy link
Contributor

Implicitly enabling plugin by checking for core dependency may confuse users, who may not realise that simply adding a dependency will generates code at compile time.

I prefer the configuration of compose, by setting to true to enable a plugin:

serialization {
    enable = true
}

And then we can enable the officially supported format in the same scope:

serialization {
    enable = true
    json = true
    protobuf = true
    // Or this way
    useFormat(Json, Protobuf)
}

@sandwwraith
Copy link
Member

sandwwraith commented Sep 2, 2024

I'd like to point out that code generation is performed only for @Serializable classes and serializer() function. So even if core dependency is included and serialization plugin is enabled, no code generation happens unless it is explicitly requested by the annotation.

@pdvrieze
Copy link
Contributor

pdvrieze commented Sep 2, 2024

From that perspective I guess the checking for the library is more an optimization rather than anything else (btw. does the plugin just check that certain types exist on the class path?).

Btw. when I mention cost it is more the "human" costs of confusion and/or setting precedents, not per se the processing/overhead cost.

@qwwdfsad
Copy link
Member Author

qwwdfsad commented Sep 2, 2024

The idea behind the auto-enabled plugin is that it is enabled by default, and knows nothing about whether the project has any specific dependencies.

What we can do to further push on Compose-like configuration is KGP DSL:

dependencies {
    kotlin("serialization")
    kotlin("json")
    kotlin.json
}

but it comes with a little bit different tradeoffs and should be considered in a bigger scope with the rest of core libraries

@hfhbd
Copy link
Contributor

hfhbd commented Sep 2, 2024

I like the idea of automatic applying the serialization plugin because you always need to use the same KGP version (that needs to be applied too), and different plugin and runtime versions are confusing, especially for beginners.
But I don't think, additionally Gradle "magic"/shortcuts are helpful because you do need to pass the runtime versions somehow, and you don't want to hardcore the runtime version in KGP, because this would result into the same (slow) release cadence.

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

No branches or pull requests

6 participants