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

Support Kotlin Multiplatform #6417

Open
yschimke opened this issue Dec 26, 2024 · 8 comments
Open

Support Kotlin Multiplatform #6417

yschimke opened this issue Dec 26, 2024 · 8 comments

Comments

@yschimke
Copy link

For KMP projects using org.jetbrains.kotlin.multiplatform instead of org.jetbrains.kotlin.jvm, the Bnd Gradle plugin has a bunch of broken assumptions.

		project.getPluginManager()
			.apply("java");

This API conflicts with the Android support in KMP, so can't be applied.

And even if trying to use to lower level task APIs,

		SourceSet mainSourceSet = sourceSets(project).getByName(SourceSet.MAIN_SOURCE_SET_NAME);

calls the following which fails as it isn't configured.

	public static SourceSetContainer sourceSets(Project project) {
		SourceSetContainer sourceSets = project.getExtensions()
			.getByType(JavaPluginExtension.class)
			.getSourceSets();
		return sourceSets;
	}

Is it possible to use this plugin without assuming the Java plugin, and using conventions? I guess mainly around these differences https://stackoverflow.com/questions/78536805/what-is-the-difference-between-org-jetbrains-kotlin-android-and-org-jetbrains-ko

@yschimke
Copy link
Author

I'm trying to work around with questionable hacks like

val jarTask = tasks.getByName<Jar>("jvmJar")
val compileTask = tasks.named("jvmMainClasses")

// Hack to make BundleTaskExtension pass briefly
project.extensions
  .getByType(JavaPluginExtension::class.java)
  .sourceSets.create("main")

val bundleExtension = jarTask.extensions.create(
  BundleTaskExtension.NAME,
  BundleTaskExtension::class.java,
  jarTask,
)

bundleExtension.run {
  classpath(libs.kotlin.stdlib.osgi.map { it.artifacts }, compileTask.map { it.outputs })
  bnd(
    "Export-Package: okhttp3,okhttp3.internal.*;okhttpinternal=true;mandatory:=okhttpinternal",
    "Import-Package: " +

@pkriens
Copy link
Member

pkriens commented Jan 2, 2025

@bjhargrave got some time to comment on this and advise?

@bjhargrave
Copy link
Member

I don't have any knowledge of Kotlin Multiplatform. The Bnd gradle plugin is based upon the assumption that the Kotlin gradle plugin "extends" the gradle java plugin which we (Bnd) then used to configure in support. But it appears the Kotlin multiplatfrom gradle plugin does not do this and does something else. So the Bnd gradle plugin would need a bunch of changes to handle this change in how the Kotlin multiplatfrom gradle plugin now works. It is probably non-trivial and unspecified (as it was before), so any fix here would need some spelunking in the Kotlin multiplatfrom gradle plugin code to figure what it now does and how the Bnd gradle plugin can configure it. Since this behavior is probably unspecified, an updated Bnd gradle plugin would likely break in the future when different changes are made to how the Kotlin gradle plugins works.

How gradle works and the plugins in the gradle ecosystem work are a moving target that takes a fair bit of work to keep current with in terms of keeping the Bnd gradle plugin working.

@pkriens
Copy link
Member

pkriens commented Jan 2, 2025

thanks @bjhargrave

@yschimke this looks beyond the effort we can afford. Are you willing to provide a PR and maintain it?

@yschimke
Copy link
Author

yschimke commented Jan 2, 2025

I'm not an expert on this, but my rough understanding is.

The Kotlin plugin does "extend the gradle java plugin".

https://discuss.gradle.org/t/javaplugin-vs-javabaseplugin/45516

The Kotlin plugin also tries to simulate the Java structure so Java plugins just work, but there do seem to be differences.

https://github.com/JetBrains/kotlin/blob/bcea3f35d86e29de5d9132ae84d6527c8e45ffa1/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt#L139

        // Below, some effort is made to ensure that a user or 3rd-party plugin that inspects or interacts
        // with the entities created by the Java plugin, not knowing of the existence of the Kotlin plugin,
        // sees 'the right picture' of the inputs and outputs, for example:
        // * the relevant dependencies for Java and Kotlin are in sync,
        // * the Java outputs contain the outputs produced by Kotlin as well

But the Bnd plugin seems to assume the concrete implementation. So maybe it's enough to not apply the java plugin, and ask developers to apply one first?

Some other plugins that have gone through this to varying degrees

xvik/gradle-animalsniffer-plugin@412ae82

https://github.com/vanniktech/gradle-maven-publish-plugin/blob/main/plugin/src/main/kotlin/com/vanniktech/maven/publish/MavenPublishBaseExtension.kt

@yschimke
Copy link
Author

yschimke commented Jan 2, 2025

@pkriens Unfortunately this is not in my area of expertise or passion enough to volunteer to provide a PR or maintain it.

My interest for Bnd, extends only to support some niche users of OkHttp who it is apparently very important for. If the kludgy code above works, then I'll leave it like that. If it breaks or becomes a burden for us, I'll discuss options or raise specific bugs.

But overall Kotlin multiplatform is popping up in a lot of JVM libraries, it seems like this will be increasingly common if Kotlin adoption continues.

@pkriens
Copy link
Member

pkriens commented Jan 3, 2025

Thanks for the reply. I see the importance but we just lack the man power and people with this (financial) interest to do the heavy lifting.

But I understand you only use this to generate the OSGi headers?

@yschimke
Copy link
Author

yschimke commented Jan 3, 2025

@pkriens Yep. Perhaps leave this open then, but put in the icebox, I can point to it and try to get a sense of how many other projects need it.

This is the config for most Jar projects - https://github.com/square/okhttp/blob/master/buildSrc/src/main/kotlin/Osgi.kt

This is the specific config for the core module which is KMP (android and JVM) - https://github.com/square/okhttp/blob/master/okhttp/build.gradle.kts#L222

This is our test that we are generating valid bundles(?) - https://github.com/square/okhttp/blob/master/okhttp-osgi-tests/src/test/kotlin/okhttp3/osgi/OsgiTest.kt

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

No branches or pull requests

3 participants