ClassNotFoundException error for Kotlin (non-andro

2019-04-11 20:11发布

问题:

I attempted to create a normal Kotlin project (non-android, just desktop/command line project) with Android Studio 2.3.3.

I followed the steps as laid out here but with different build.gradle content whose content I shared here.

Actually that content of build.gradle I copied from build.gradle file after generating a new project with IntelliJ Community Edition (2017.2).

Then I create a configuration to be able to run it on desktop with proper set up like Main Class, Working directory, and Use classpath of module. You can see in the image below.

and following is the project file structure I have

Then I sync the project, it succeeds. But error kicks in when I try to Run the project. I got the following error.

    "/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java" -Didea.launcher.port=7534 "-Didea.launcher.bin.path=/Applications/Android Studio.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/charsets.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/localedata.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/sunec.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/jce.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/jsse.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/management-agent.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/resources.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/rt.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/dt.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/jconsole.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/sa-jdi.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/tools.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.4-2/272a21c30432c943d618008fbbd34762eb0d6c8a/kotlin-stdlib-jre7-1.1.4-2.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.4-2/fec983b2608a8a91a1b87dba18d247d692cf6b51/kotlin-stdlib-1.1.4-2.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.4-2/168cc3f45c307edda6c867dd0635a7d451257551/kotlin-stdlib-jre8-1.1.4-2.jar:/Applications/Android Studio.app/Contents/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain io.wasin.testjavaapp.Main
Exception in thread "main" java.lang.ClassNotFoundException: io.wasin.testjavaapp.Main
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:123)

Process finished with exit code 1

I saw the classpath parameter as supplied in above /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java has no related directory to my project. I don't know how to add classpath directory via gradle despite I set up it in configurations already.

How can I solve this problem?

Update:

The following is my Main.kt code. It's just for testing purpose. So just printing something out.

package io.wasin.testjavaapp

object Main {
    @JvmStatic fun main(arg: Array<String>) {
        println("Hello world")
    }
}

Also I updated build.gradle for Kotlin version to match the version of Kotlin plugin on Android Studio. It's now ext.kotlin_version = '1.1.4-2'. Although still doesn't solve the problem.

Update 2

I checked inside build directory at the same level of src directory. There are no .class or intermediates files generated/built over there, only kotlin-build/caches/version.txt and that's it. No other files. So the problem might be due to the source files are not compiled at all?

Update 3

I tried creating a new module to see if it's the root cause or not. Also created assets folder just to act as Working Directory, rearranged source folder again to be as following.

We now have 2 modules.

  1. testJavaApp - root one
  2. desktop - consists of Main.kt and used as desktop executable

testJavaApp has the following code for build.gradle

group 'io.wasin'
version '1.0-SNAPSHOT'

// Top-level build file where you can add configuration options common to 
all sub-projects/modules.
buildscript {
    ext.kotlin_version = '1.1.4-2'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

also desktop module has following code for build.gradle

apply plugin: 'kotlin'

sourceSets.main.java.srcDirs = [ "src/" ]
project.ext.mainClassName = "io.wasin.testjavaapp.Main"
project.ext.assetsDir = new File("../assets");

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
repositories {
    mavenCentral()
}

task run(dependsOn: classes, type: JavaExec) {
    main = project.mainClassName
    classpath = sourceSets.main.runtimeClasspath
    standardInput = System.in
    workingDir = project.assetsDir
    ignoreExitValue = true
}

Unfortunately, it still didn't work and it's the same error that shown up.

Update 4

@aristotll provided info in a comment that he tested with Android Studio and faced the same problem, but not with IntelliJ. He said it might be Android Studio bug. So I guess, I would try a few more times then decide whether it's solid enough to report as a bug. Thanks for taking time to testing out.

回答1:

I also met this problem and solved it.

Add runtimeClasspath files("build/classes/kotlin/main") in build.gradle

dependencies {
    // This dependency is found on compile classpath of this component and consumers.
    compile 'com.google.guava:guava:23.0'

    // Use JUnit test framework
    testCompile 'junit:junit:4.12'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile group: 'dom4j', name: 'dom4j', version: '1.6.1'
    runtimeClasspath files("build/classes/kotlin/main")
}

because Android Studio doesn't find classes in build/classes/kotlin/main. Add runtimeClasspath and it works!