简体   繁体   中英

Kotlinx Coroutines classes not found when running from the artifact's .jar

I am developing a Kotlin desktop app on IntelliJ Idea IDE that uses kotlinx coroutines.

Here is my build.gradle file:

plugins {
    id 'application'
    id 'org.jetbrains.kotlin.jvm' version '1.3.60'
}

mainClassName = 'MainKt'

group 'my_group_name'
version '1.01'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'

    // Coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2'

}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

jar {
    manifest {
        attributes 'Main-Class': 'MainKt'
    }

    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

Everything works fine when running the project through the IDE , but when I generate the .jar artifact and run it through java -jar file.jar , the following exception is thrown when a class of the coroutines is used:

Exception in thread "Thread-2" java.lang.NoClassDefFoundError: kotlinx/coroutines/GlobalScope
Caused by: java.lang.ClassNotFoundException: kotlinx.coroutines.GlobalScope
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)

Why doesn't the Kotlinx Coroutines work when running java -jar file.jar on the generated .jar artifact?

After a long time looking for the solution to this problem, I found two ways to solve it.


First

The generated .jar artifact did not contain that Kotlinx coroutines classes because the artifact was setup on IntelliJ Idea before the coroutines was added as a dependency.

Due to this, the artifact configuration did not include the Kotlinx coroutines (it seems that it does not sync with new dependencies additions and deletions).

To solve that problem, one could:

  • manually add the dependency to the artifact generation configuration (on Project Settings), or;
  • delete the configuration and create it again.

Second

Create a fatJar task o gradle as follows

jar {
    manifest {
        attributes 'Main-Class': 'MainKt'
    }
}

task fatJar(type: Jar) {
    manifest {
        attributes 'Main-Class': 'MainKt'
    }
    baseName = project.name
    from {
        configurations.runtimeClasspath.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    with jar
}

and run that gradle task

gradle fatJar

The output can be found under build/libs .


Hope this helps anyone else that is going through that same problem :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM