I'm a beginner with gradle and would like to use koin in my Kotlin project.
However, I get the following error
Execution failed for task ':compileTestKotlin'.
> Error while evaluating property 'filteredArgumentsMap' of task ':compileTestKotlin'
> Could not resolve all files for configuration ':testCompileClasspath'.
> Could not resolve org.jetbrains.kotlin:kotlin-test-junit5:1.6.20.
Required by:
project : > org.jetbrains.kotlin:kotlin-test:1.6.20
> Module 'org.jetbrains.kotlin:kotlin-test-junit5' has been rejected:
Cannot select module with conflict on capability 'org.jetbrains.kotlin:kotlin-test-framework-impl:1.6.20' also provided by [org.jetbrains.kotlin:kotlin-test-junit:1.6.10(junitApi)]
> Could not resolve org.jetbrains.kotlin:kotlin-test-junit:1.6.10.
Required by:
project : > io.insert-koin:koin-test:3.2.0-beta-1 > io.insert-koin:koin-test-jvm:3.2.0-beta-1
> Module 'org.jetbrains.kotlin:kotlin-test-junit' has been rejected:
Cannot select module with conflict on capability 'org.jetbrains.kotlin:kotlin-test-framework-impl:1.6.10' also provided by [org.jetbrains.kotlin:kotlin-test-junit5:1.6.20(junit5Api)]```
This is my gradle.build.kts file
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val koinVersion = "3.2.0-beta-1"
plugins {
kotlin("jvm") version "1.6.20"
kotlin("plugin.serialization") version "1.6.10"
application
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
implementation("io.insert-koin:koin-core:$koinVersion")
testImplementation("io.insert-koin:koin-test:$koinVersion")
testImplementation("io.insert-koin:koin-test-junit5:$koinVersion")
testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25")
testImplementation(kotlin("test"))
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
application {
mainClass.set("MainKt")
}
It looks like there are 3 problems
As I mentioned in the comment, the Kotlin JVM and Serialization plugins have mismatched versions. These should always be the same!
plugins {
kotlin("jvm") version "1.6.21"
kotlin("plugin.serialization") version "1.6.21"
application
}
However, as you discovered, it still doesn't work. There's a larger error message, with three errors.
Could not resolve io.insert-koin:koin-test-junit5:3.2.0-beta-1
Could not resolve org.jetbrains.kotlin:kotlin-test-junit5:1.6.21
Could not resolve org.jetbrains.kotlin:kotlin-test-junit:1.6.10
Let's go through them one-by-one
Java 11 library, Java 8 project
Here's the reason that Gradle gives for the first failure:
Could not resolve io.insert-koin:koin-test-junit5:3.2.0-beta-1.
No matching variant of io.insert-koin:koin-test-junit5:3.2.0-beta-1 was found. The consumer was configured to find an API of a library compatible with Java 8, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but
Incompatible because this component declares a component compatible with Java 11 and the consumer needed a component compatible with Java 8
The component, koin-test-junit5, is only compatible with Java 11, but your project needs Java 8 (kotlinOptions.jvmTarget = "1.8").
Let's fix this first, using Gradle Toolchain
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.jvmTarget = "11"
}
kotlin {
jvmToolchain {
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(11))
}
}
That resolves the Java version mis-match, and leaves two more errors.
conflict on capability - incompatible libraries
Cannot select module with conflict on capability
Cannot select module with conflict on capability 'org.jetbrains.kotlin:kotlin-test-framework-impl:1.6.10' also provided by [org.jetbrains.kotlin:kotlin-test-junit:1.6.10(junitApi)]
Cannot select module with conflict on capability 'org.jetbrains.kotlin:kotlin-test-framework-impl:1.6.10' also provided by [org.jetbrains.kotlin:kotlin-test-junit5:1.6.10(junit5Api)]
Understanding this one requires quite a bit of knowledge of how Gradle selects versions.
tl;dr: org.jetbrains.kotlin:kotlin-test-junit and org.jetbrains.kotlin:kotlin-test-junit5 are incompatible. You can only use one or the other - not both
I don't really understand what Koin needs to work best. It looks like it has a hard dependency on JUnit5, so you'd have to use these dependencies, and wouldn't be able to use kotlin("test")
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
implementation("io.insert-koin:koin-core:$koinVersion")
testImplementation("io.insert-koin:koin-test:$koinVersion")
testImplementation("io.insert-koin:koin-test-junit5:$koinVersion")
testImplementation("com.willowtreeapps.assertk:assertk:0.25")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.2")
// incompatible with JUnit 5, which I think is required by Koin?
// testImplementation(kotlin("test"))
}
Explanation
In short, when you use Gradle to build a library, you can declare 'attributes'. They're free-form strings, so they can really be anything. They describe things like "this library needs Java 11" or "this is test coverage data".
Some attributes are important to Gradle resolving a project's dependencies. The error you originally got was caused by one such attribute: 'capability'. It describes the Maven coordinates that the library produces.
In the case of the Maven coordinates, if they clash, then Gradle doesn't know what to do, and throws an error. It's up to the user to fix it. There's a lot of Gradle docs about conflict resolution, but usually the simplest answer is to is remove any conflicting dependencies.
What's interesting about capabilities is that because it's just a string, you can add anything to it. And what the authors of org.jetbrains.kotlin:kotlin-test-junit5 and org.jetbrains.kotlin:kotlin-test-junit have done is given them both the same capability.
org.jetbrains.kotlin:kotlin-test-framework-impl:1.6.10
If you search for this library you'll find it doesn't exist. That's because the capability is completely artificial! The authors have made it up, specifically so Gradle will throw an error, and it's up to the user to fix it.
So that's the fix: choose either kotlin-test-junit or kotlin-test-junit5, because you can't have both.
I think org.jetbrains.kotlin:kotlin-test-junit5 has problem with dependencies.
I also struggled with the same issue, so I tried multiple solutions but it all fails.
And I realized that, when just add dependency for kotlin-test-junit5, the kotlin-test-junit is also added to the external libraries.
So here's the working solution for me.
I added this line to gradle first to enable useJunitPlatform()
tasks.withType<Test> {
useJUnitPlatform()
}
after that, i exclude kotlin-test-junit from every references like this,
testImplementation("io.ktor:ktor-server-tests-jvm:$ktorVersion")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:$kotlinVersion") {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-test-junit")
}
// Dependency Injection
val koinVersion: String by project
implementation("io.insert-koin", "koin-ktor", koinVersion)
implementation("io.insert-koin", "koin-logger-slf4j", koinVersion)
testImplementation("io.insert-koin", "koin-test-junit5", koinVersion) {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-test-junit")
}
After that, junit5 test was working perfectly.
Related
I've created a KMM project, and also an Xcode project with a build phase that calls ./gradlew embedAndSignAppleFrameworkForXcode. It runs successfully, but generates a .framework, not an .xcframework; and we really need the latter for modern Xcode.
Am i missing something? I read that modern versions of kotlin can generate the xcframework directly, but i'm not sure how. Is there a gradle task for this?
Thanks so much :)
According to Kdoctor, I have:
Xcode 14.1
Android studio 2021.3
Kotlin Plugin: 213-1.7.20
Kotlin MM plugin: 0.5.1(213)-60
You should declare your XCFrameworks, then it'll register three tasks for you.
assembleXCFramework, assembleDebugXCFramework, and assembleReleaseXCFramework.
Here is an example of build.gradle:
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
plugins {
kotlin("multiplatform")
}
kotlin {
val xcf = XCFramework()
val iosTargets = listOf(iosX64(), iosArm64(), iosSimulatorArm64())
iosTargets.forEach {
it.binaries.framework {
baseName = "shared"
xcf.add(this)
}
}
}
For more information, visit kotlin docs.
I have a live react native app, which was working fine. But now I need to made some changes to it but I am unable to do so after new updates and new gradle version. I have tried on multiple PCs and workspaces but all are of no use same error on every system pops up. giving some errors which are as under and attached screenshot.
FAILURE: Build failed with an exception.
The Kotlin Gradle plugin was loaded multiple times in different subprojects, which is not supported and may break the build.
This might happen in subprojects that apply the Kotlin plugins with the Gradle 'plugins { ... }' DSL if they specify explicit versions, even if the versions are equal.
Please add the Kotlin plugin to the common parent project or the root project, then remove the versions in the subprojects.
If the parent project does not need the plugin, add 'apply false' to the plugin line.
See: https://docs.gradle.org/current/userguide/plugins.html#sec:subprojects_plugins_dsl
The Kotlin plugin was loaded in the following projects: ':react-native-alarm-clock', ':react-native-webview'
What went wrong:
Execution failed for task ':invertase_react-native-apple-authentication:compileDebugKotlin'.
Screenshot of the error
another Screenshot of the error
I have a live react native app, which was working fine. But now I need to made some changes to it but I am unable to do so. I have tried on multiple PCs and workspaces but all are of no use same error on every system pops up.
add kotlin version in you android/build.gradle
buildscript {
ext {
...
kotlin_version='1.6.0' //add This change version with your installed kotlin version
...
}
repositories {
google()
mavenCentral()
}
dependencies {
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" //add This
...
}
}
Just go to build.gradle(Project:yourProjectName)
change
Plugin {
...
id 'org.jetbrains.kotlin.android' version '1.4.x' apply false
...
}
To
Plugin {
...
id 'org.jetbrains.kotlin.android' version '1.6.0' apply false
...
}
Note: Error may be different but if you are getting any error when taking android build without any changes in code for past two days
My Error - Failed to install the app. Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
error Failed to install the app. Make sure you have the Android development environment set up:
Error: Command failed: ./gradlew app:installDebug
-PreactNativeDevServerPort=8081
FAILURE: Build failed with an exception.
* Where: Build file '/Users/....../node_modules/react-native-month-year-picker/android/build.gradle' line: 115
* What went wrong: A problem occurred configuring project ':react-native-month-year-picker'.
> Could not resolve all files for configuration ':react-native-month-year-picker:implementation'.
> Could not resolve com.facebook.react:react-native:+.
Required by:
project :react-native-month-year-picker
> Cannot choose between the following variants of com.facebook.react:react-native:0.71.0-rc.0:
- debugVariantDefaultRuntimePublication
- releaseVariantDefaultRuntimePublication
All of them match the consumer attributes:
- Variant 'debugVariantDefaultRuntimePublication' capability com.facebook.react:react-native:0.71.0-rc.0:
The build failures for Android was due to the publish of the React Native version 0.71.0-rc0.
Note: Error may be different but this would be the solution if you are getting android build failures without any changes in code for past two days
before trying these methods please revert back every changes you have done : https://stackoverflow.com/a/74371195/10657559
Method 1
Add this fix to your android -> build.gradle file as follows:
buildscript {
// ...
}
allprojects {
repositories {
exclusiveContent {
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url "$rootDir/../node_modules/react-native/android"
}
}
}
// ...
}
}
What this fix will do is apply an exclusiveContent resolution rule that will force the resolution of React Native Android library, to use the one inside node_modules
Method 2
If your gradle doesn't support above, then add this to your android -> build.gradle file as follows:
def REACT_NATIVE_VERSION = new File(['node', '--print',"JSON.parse(require('fs').readFileSync(require.resolve('react-native/package.json'), 'utf-8')).version"].execute(null, rootDir).text.trim())
buildscript {
// ...
}
allprojects {
configurations.all {
resolutionStrategy {
force "com.facebook.react:react-native:" + REACT_NATIVE_VERSION
}
}
// ...
}
Ref: Fix and updates on Android build failures happening since Nov 4th 2022 #35210
Adding on to the voted answer to do some knowledge sharing.
To reiterate, as #Thanhal has posted, the solution and official explanation can be found here: Android build failures No matching variant of com.facebook.react:react-native:0.71.0-rc.0 was found.
The biggest question I needed answer following the error was:
After specifying my react-native version in package.json, why does my project still download another react-native version?
I even used npm install --save-exact to ensure I am getting the correct version
The error message I was given left me even more confused:
The class is loaded from ~/.gradle/caches/transforms-3/9a8c596b7e1788d5bad7c80991eefff1/transformed/jetified-kotlin-stdlib-1.6.10.jar!/kotlin/Unit.class
e: .../node_modules/expo-modules-core/android/src/main/java/expo/modules/adapters/react/permissions/PermissionsService.kt: (351, 32): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.1.
Somehow Kotlin became an issue for me as well.
Who / What is asking for the latest react-native?
For my case, the issue here wasn't about the version of react-native my project is using. It was about what my libraries are using.
The react-native team had been shipping a Maven Repository inside the NPM package (node_modules/react-native/android/) up till 0.71.0-rc.0. Most of the libraries have their build.gradle configured to reference to this directory. This is done through declaring a custom repository in the libraries' build.gradle:
maven {
url "$rootDir/../node_modules/react-native/android"
}
But in the libraries' build.gradle files, more repositories are declared, which may look like this:
repositories {
maven {
url "$rootDir/../node_modules/react-native/android"
}
google()
mavenLocal()
mavenCentral()
}
Then, the dependency for the library is declared as so:
dependencies {
implementation 'com.facebook.react:react-native:+'
}
Because the "+" as version for the react-native dependency, Gradle will take the latest react-native version from the various declared repositories.
Since in the past react-native was shipped with npm package, the latest which Gradle will always take the react-native in node_modules. However, now that the react-native team is publishing the library to public repositories including MavenCentral, Gradle honours the "+" and take the version on MavenCentral instead.
Why did I get the Kotlin error?
My project uses an older version of react-native and as of version 0.68 react-native started using Kotlin version 1.6.10 (see the change history). So yes, the difference in react-native version would also result in Kotlin error.
Facebook has release bugfix versions for >=0.63. You can upgrade instead of apply the hotfix also.
https://github.com/facebook/react-native/issues/35210
This fix works:
Reason for Failures : The build failures for Android was due to the publish of the React Native version 0.71.0-rc0 to Maven and because of which when the gradle is syncing its picking this 0.71.0-rc0 version of react-native rather then your current version of react-native.
Made it work without upgrading react-native version and by adding this in build.gradle, this works (hermes enabled or not, along with flipper too)
exclusiveContent {
// We get React Native's Android binaries exclusively through npm,
// from a local Maven repo inside node_modules/react-native/.
// (The use of exclusiveContent prevents looking elsewhere like Maven Central
// and potentially getting a wrong version.)
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url "$rootDir/../node_modules/react-native/android"
}
}
}
final snippet looks like this
allprojects {
repositories {
exclusiveContent {
// We get React Native's Android binaries exclusively through npm,
// from a local Maven repo inside node_modules/react-native/.
// (The use of exclusiveContent prevents looking elsewhere like Maven Central
// and potentially getting a wrong version.)
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url "$rootDir/../node_modules/react-native/android"
}
}
}
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
gradle clean and rebuild after this fix. Then you can react native run android successfully.
What this fix will do is apply an exclusiveContent resolution rule that will force the resolution of React Native Android library, to use the one inside node_modules
Now,
There are some patch releases from react native for different versions, If you dont want to put this fix,
you can update your current react native version to the react native patch version as mentioned here
https://github.com/facebook/react-native/issues/35210
I have a Kotlin multiplatform project and the newest version of IDEA started to complain about #JvmStatic usages in interfaces:
What's weird is that I added the necessary config to my build.gradle.kts file:
kotlin {
jvm {
withJava()
jvmTarget(JavaVersion.VERSION_1_8)
}
// ...
}
and I also set it up in IDEA here:
and here:
and I also added the compiler parameter as IDEA suggested. What am I doing wrong?
If I build the project from the command line I get a BUILD SUCCESSFUL.
This is a bug with multiplatform projects Gradle IDEA import: https://youtrack.jetbrains.com/issue/KT-43074. In this particular case it is acceptable to suppress the error until the bug is fixed:
#Suppress("JVM_STATIC_IN_INTERFACE_1_6") // remove when KT-43074 is fixed
fun empty() = ...
class Foo(
val name: Identifier,
val trKey: String = "action.${name.toString().replace(':', '.')}"
// ^~~~~~~ this is unresolved
) {
// Members
}
The replace function is able to be resolved in Fabric's source code and it does run, but it doesn't in my Kotlin code.
I've tried setting the project SDK to 1.8, 11, and Kotlin SDK, and none of them seem to solve this issue. In fact, putting the SDK to 11 makes java.lang.String inaccesible.
I think I fixed it by adding KotlinRuntime into libraries through IntelliJ project structure (will get erased by Gradle import), or with gradle dependencies adding Kotlin library.
Instead I found changing JDK version back to 1.8 fixes this issue and is reproducable. The above only worked once for me.