How to import KotlinMultiplatformExtension inside buildSrc module? - kotlin

I am developing a kotlin multiplatform project, which has a bunch of modules.
I have written an extension function which is meant to be used inside each module. The extension function extends functionality of KotlinMultiplatformExtension class. Now that code is repeated inside each module's build.gradle.kts file. So i thought it would be great to move that code to buildSrc moudle and reuse everywhere.
The problem is that inside buildSrc module KotlinMultiplatformExtension is not resolved.
My buildSrc/build.gradle.kts:
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
If i right click KotlinMultiplatformExtension inside someModule/build.gradle.kts
it takes me to:
So I guessed that adding a dependency inside buildSrc/build.gradle.kts should help:
dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
}
But adding that results with an error:
* Exception is:
java.lang.NoClassDefFoundError: com/android/build/gradle/BaseExtension
at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.configureTarget(KotlinPlugin.kt:765)
at org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin$Companion.applyToTarget(KotlinPlugin.kt:727)
at org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin.apply(KotlinPlugin.kt:689)
at org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin.apply(KotlinPlugin.kt:678)
at org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper.apply(KotlinPluginWrapper.kt:102)
Any ideas how to make KotlinMultiplatformExtension available inside buildSrc?

Turns out that changing
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
into
compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
resolves problem with the exception (java.lang.NoClassDefFoundError: com/android/build/gradle/BaseExtension)
and makes KotlinMultiplatformExtension available inside the buildSrc's source files.
solution found here:
https://github.com/gradle/gradle/issues/9209

Related

Kotlin build gradle ~ dependencies resolves as type DependencyHandlerScorpe instead of KotlinDependencyHandler

I am currently observing the following very curious behavior in the build.gradle.kts files of one of my projects:
Basically, I have two modules, and the same import works in one, but not in the other. Upon close inspection, I have noted what I believe might be the root of the problem, though I have no idea why it happens or what to do against it.
The core of what I want to do is to get this import running:
kotlin {
[...]
sourceSets {
val commonMain by getting
dependencies {
implementation(Dependencies.eventBus)
}
[...]
}
}
}
In the module on the left, that works just fine. However, in the module on the right, it doesn't. The differences that I can observe are that for some strange reason, the getting is syntax-highlighted in purple instead of yellow on the right, and dependencies is of the type this: DependencyHandlerScope instead of this: KotlinDependencyHandler.
And now the really strange thing: In the very next block below that (commonTest) it behaves "correctly" again (as in: like in the left module, where the import works).
What is going on here? Is this really the reason why my import fails to resolve? And if so, what can I do against it?
Okay, so after I spent a bit more time looking at it, I found the issue: I was missing a pair of curly braces around the dependencies block in that one case, so this is how it ought to look, which is visually very similar, yet syntactically apparently a big difference:
kotlin {
[...]
sourceSets {
val commonMain by getting {
dependencies {
implementation(Dependencies.eventBus)
}
}
[...]
}
}

Can't use a font in Kotlin Multiplatform

Pretty simple; just created a Compose Multiplatform project from the wizard.
Went ahead and created the Theme; but I wanted to use the same font so I put poppins.ttf inside commonMain/resources/font/.
Then I declared the following in commonMain module:
expect val projectFontFamily: FontFamily
On the commonDesktop module I used:
actual val projectFontFamily: FontFamily = FontFamily(
Font("font/poppins.ttf")
)
Great, that worked. Now on commonAndroid:
actual val projectFontFamily: FontFamily = FontFamily(
Font(R.font.poppins)
)
For some reason the R class is not properly being generated and I cannot use R.font.poppins.
If I rename "resources" to "res" and shove the font into res/font/ then it works. (But I just duplicated the font file).
How do I get around doing this?
It turns out it's rather a gradle issue and some inexperience with KMM.
Kotlin multiplatform projects by default (regardless of the platform) provide their resources in a folder called resources inside each module.
Problem is that the default folder for Android needs to be called res
So you can apply a fix either way:
Change resources folders to res and modify gradle accordingly or indicate in the Android project that the resource folder is not res but resources.
We ended up doing the latter in our project
// build.gradle.kts
android {
...
sourceSets["main"].res.srcDirs(
"src/commonMain/resources",
"src/androidMain/resources"
)
...
}

kotlin multi-platform to javascript : naming of the method not respected

I use the gradle kotlin multi-platform plugin to build something in java and js
My issue is in the js version, the name of the function/class is not consistent:
in my kotlin, I define a function "launch()", in the js buid, it will be "launch12434()"
any idea how to correct-it?
You can use the #JsName annotation to give a specific name for your method. It looks like this;
#JsName("launch")
fun launch() {
}
More info here.

Why is a reference to dagger component unresolved, although this component is generated?

I use Kotlin with Dagger 2. I created an interface DataComponent with #Component annotation.
I see that DaggerDataComponent is generated under build/generated/source/kapt/[package path].
When I try to use DaggerDataComponent I get the Unresolved reference: DaggerDataComponent compile time error.
Why is the reference to DaggerDataComponentunresolved, although DaggerDataComponent is generated?
Found a related problem on Kotlin bugtracker. And although they report that bug is fixed it is still reproduced.
Adding the following to module level build.gradle resolved an issue for me:
idea {
module {
sourceDirs += file('build/generated/source/kapt/main')
generatedSourceDirs += file('build/generated/source/kapt/main')
}
}

How to create subprojects inside Play with Intellij?

Currently I have the following Play project structure:
PlayApp
modules
common
sub_project_two
PlayApp is marked as a module, dependent on common.
modules is just a directory.
common is a sub project(also a play app).
sub_project_two is a sub project(also a play app), which is dependent on common.
Unfortunately I cannot just right click on "modules" and create new module(play app) and move on. Currently, I literally have to right click PlayApp and create the new module then move it to "modules", and it is running into dependency issues in Intellij and failing to import the classes inside "common".
What is the correct way of creating subprojects inside Intellij?
There is no any special way to create subprojects in Intellij. Subprojects are defined in sbt build file. Intellij will discover these projects and configure them as long as you have Scala plugin. I would imagine a following project structure in your build file:
lazy val PlayApp = Project("playApp", file(".")).aggregate(common, subProjectTwo)
lazy val common = Project("common", file("modules/common"))
lazy val subProjectTwo = Project("subProjectTwo", file("modules/sub_project_two"))
For more details visit: http://www.scala-sbt.org/0.13.5/docs/Getting-Started/Multi-Project.html