https://kotlinlang.org logo
#gradle
Title
# gradle
c

CLOVIS

12/04/2023, 8:37 PM
I have applied the
kotlin("multiplatform")
plugin to a build. When running
./gradlew :components
, I get:
Copy code
No components defined for this project.
Note: currently not all plugins register their components, so some components may not be visible here.
Is this planned? Is there a reason in particular this cannot be done? I would like to add a new variant to the Kotlin Multiplatform artifacts, by having it be mentioned in the Gradle Module Metadata for the Multiplatform publication. Is there another way to add information to it?
👀 1
j

Jeff Lockhart

12/04/2023, 10:24 PM
You might find this issue I created relevant. In my case, I needed to add Gradle Module Metadata to an Android component. The Android Gradle plugin uses the Kotlin Gradle plugin under the hood. I was able to access the
AdhocComponentWithVariants
reference via reflection. It would be nice if my PR got a look to open up the API directly.
1
m

mbonnin

12/04/2023, 10:53 PM
I was using reflection too. Issue upvoted
thank you color 1
c

CLOVIS

12/05/2023, 8:55 AM
…why does the KGP team always do things differently from the Gradle team? 😐
Thank you both for the workarounds.
thank you color 2
I have a task that generates a ZIP file. I also have an outgoing configuration that contains that ZIP file (added as artifact) as well as multiple variant declarations. I'd like to add this configuration to the multiplatform component's Gradle Module Metadata so it can be found using variant-aware dependency resolution under the same artifact name as the project itself. I tried to use @mbonnin's workaround but I'm confused: it gives me access to a few
KotlinTargetComponent
s, but these don't seem to implement
AdhocComponentWithVariants
, so how I can add my own variants to them?
j

Jeff Lockhart

12/07/2023, 7:59 PM
My use case was with an Android module and seems this API has changed in 1.9.20, since I accessed it with reflection, invalidating my PR. (I'm assuming this will affect my code after updating to an AGP version using a version of the KGP with this API change.) It looks like the
AdhocComponentWithVariants
reference should be accessible alongside the
KotlinTargetComponent
reference if you can go up another level to the
KotlinTargetSoftwareComponent
object. And it appears you can get the
KotlinTargetSoftwareComponent
reference from the
KotlinTarget.components
property, rather than
KotlinTarget.kotlinComponents
in @mbonnin’s reflection method, which looks to be accessible without reflection, but possibly requiring an opt-in. You might try casting to
KotlinTargetSoftwareComponentImpl
and accessing
adhocComponent
via reflection.
c

CLOVIS

12/09/2023, 11:53 AM
I see. I managed to get a
KotlinTargetSoftwareComponent
instance following what you said, but I'm not sure how to access the
AdhocComponentWithVariants
from that. Using
component::class.members.find { it.name == "adhocComponent" }
, I do get access to the field, however if I try to
call
it I get:
Copy code
class kotlin.reflect.jvm.internal.calls.CallerImpl$FieldGetter cannot access a member of class org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetSoftwareComponentImpl with modifiers "private final"
Since it's a
private
field, no getter is generated, so I cannot use Java reflection with
setAccessible(true)
. Is there another way to access the field?
j

Jeff Lockhart

12/09/2023, 6:27 PM
You should be able to call
setAccessible(true)
on a field reference. Try:
Copy code
val adHocField = Class.forName("org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetSoftwareComponentImpl")
    .declaredFields.find { it.type == AdhocComponentWithVariants::class.java }
adHocField?.isAccessible = true
c

CLOVIS

12/09/2023, 8:59 PM
Reading https://docs.gradle.org/current/userguide/publishing_customization.html, it seems that adding the variant to the AdhocComponentWithVariants should be enough for everything to be published, right? My variant looks normal to me:
Copy code
--------------------------------------------------
Variant exposedKotlinJsResources
--------------------------------------------------

Capabilities
    - example-kmp:core:unspecified (default capability)
Attributes
    - dev.opensavvy.resources    = Regular
    - org.gradle.category        = library
    - org.gradle.libraryelements = resources
Artifacts
    - build/distributions/core-kjs-assets.zip (artifactType = zip, classifier = kjs-assets)
However, it doesn't appear in the .module files when calling
./gradlew publishToMavenLocal
😕
Nevermind, it was an initialization order issue. With a small
afterEvaluate
, it now works 🙂
Thanks a lot! Now I just have some cleanup to do and I'll be able to announce this
🎉 1