IntelliJ IDEA - gradle not recognizing gradle kotlin dsl in build.gradle.kts - kotlin

I have a fresh install of IntelliJ IDEA 2022.2 (Community Edition), Gradle 7.4, and Kotlin plugin 222-1.7.10-release-334-IJ3345.118 that is not recognizing gradle kotlin dsl. I am trying to run a Ktor project that I generated on the ktor website--so I am fairly sure that the syntax is correct. I haven't made any other modifications.
The error e: /foo/build.gradle.kts:8:8: Unexpected tokens (use ';' to separate expressions on the same line)
Which is erroring out in
plugins {
application
kotlin("jvm") version "1.7.10"
id "io.ktor.plugin" version "2.1.0"
id("org.jetbrains.kotlin.plugin.serialization") version "1.7.10"
}
on the 4th line of that snippet.
Is there something special I need to do to configure Intellij to recognize that build.gradle.kts is gradle kotlin dsl and not Groovy?
Edit
As #aSemy pointed out, there is a Groovy vs Kotlin syntax mismatch that I had missed. Converting the first id to the second one fixed the syntax issue, but left me with a different issue
/foo/build.gradle.kts:8:25: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public infix fun PluginDependencySpec.version(version: String?): PluginDependencySpec defined in org.gradle.kotlin.dsl
public infix fun PluginDependencySpec.version(version: Provider<String>): PluginDependencySpec defined in org.gradle.kotlin.dsl
For my purposes, I decided to take out the library since it is described on Github to be for helping with Ktor deployments--but I'm only working locally.

Related

Gradle problems of adding koin test dependencies

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.

How to fix the `#JvmStatic` in interface usage error in IDEA when using Kotlin?

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() = ...

Kotlin, IntelliJ: math operator not working

Ubuntu Mate 20.04
IntelliJ IDEA Community 2020.2 EAP, installed through Snap
Kotlin 1.3.72, installed through Snap
JRE 1.8.0_242-8u242-b08-0ubuntu3~16.04-b08
Project set up as Kotlin: JVM|IDEA using SDK 11 (java 11.0.6)
Code:
fun main(args: Array<String>) {
var experiencePoints: Int = 5
experiencePoints += 5
println(experiencePoints)
}
has a red squiggly line under the "+=" and produces the following error:
Error:(3, 22) Kotlin: Cannot access 'java.io.Serializable' which is a supertype of 'kotlin.Int'. Check your module classpath for missing or conflicting dependencies
Changed the code to the following:
fun main(args: Array<String>) {
var experiencePoints: Int = 5
experiencePoints = experiencePoints + 5
println(experiencePoints)
}
Red squiggly line beneath the "+" character and same error.
This is Day 1 for me, following example in "Kotlin Programming, The Big Nerd Ranch Guide" by Skeen and Greenhalgh. No idea what to do about this error.
I had this in Intellij 2021.2 Ultimate on MacOS Catalina, and I did have the JDK installed. But in File -> Project Structure -> Project Settings -> Project -> Project SDK I had the Kotlin SDK selected. Makes sense, it's a Kotlin project, right? Wrong, it needs to be the Java JDK selected here.
Also under Platform Settings -> SDKs -> Kotlin SDK I was missing the Classpath. I'm not sure if this was necessary, but it was that way when I created a new Kotlin project from scratch. I ran into trouble importing an existing combined Java/Kotlin project.
I discovered that I didn't have default-jdk installed. Once I did, I found that there were extra options under File -> Project Structure -> Project -> Project SDK. I added user/lib/jvm/java-11-openjdk-amd64 java version "11.0.7" and the problem resolved.

IntelliJ shows unresolved reference to java.lang.String#replace in Fabric Kotlin dev environment

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.

Simple Intellij Kotlin project doesn't recognize LinkedHashMap or other collections

I installed the latest version of Intellij on Linux (2019.2.3 Community Edition) and added the Kotlin plugin.
I followed the Kotlin website's Getting Started with IntelliJ IDEA and created a hello world app. It worked fine until I added a LinkedHashMap. (BTW, I was running into this in a bigger project, but simplified it to this.)
This is all the code I added:
import kotlin.collections.LinkedHashMap
fun main(args:Array<String>) {
println("Hello world")
val map: LinkedHashMap<Int, String> = linkedMapOf(1 to "x", 2 to "y", -1 to "zz")
println(map)
}
I get this error on the map line:
Cannot access class 'java.util.LinkedHashMap'. Check your module classpath for missing or conflicting dependencies.
You can see I have 1.8 selected in the modules, and I verified java 8 is installed via terminal (java -version). What is the issue for this vanilla/default installation?
Ok, so I figured it out. For some reason, if I change the module to 11 (java 11) from 1.8 it just works.
Kind of weird that standard collections don't work out of the box, but... eh, I guess this works.