Kotlin Gradle 无法找到或加载主类

Posted

技术标签:

【中文标题】Kotlin Gradle 无法找到或加载主类【英文标题】:Kotlin Gradle Could not find or load main class 【发布时间】:2018-09-12 09:01:26 【问题描述】:

我尝试复制 Spring Boot Kotlin 示例项目https://github.com/JetBrains/kotlin-examples/tree/master/tutorials/spring-boot-restful。我添加了更多依赖项,当我尝试构建可执行 jar 并运行它时,出现错误:

找不到或无法加载主类...

Gradle 构建脚本

buildscript 
    ext.kotlin_version = '1.1.3' // Required for Kotlin integration
    ext.spring_boot_version = '1.5.4.RELEASE'
    repositories 
        jcenter()
    
    dependencies 
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // Required for Kotlin integration
        classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" // See https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin
        classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version"
    


/*plugins 
    id 'org.springframework.boot' version '2.0.0.RELEASE'
*/

apply plugin: 'kotlin' // Required for Kotlin integration
apply plugin: "kotlin-spring" // See https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin
apply plugin: 'org.springframework.boot'

jar 
    baseName = 'gs-rest-service'
    version = '0.1.0'
    from 
        (configurations.runtime).collect 
            it.isDirectory() ? it : zipTree(it)
        
    
    manifest 
        attributes 'Main-Class': 'org.jetbrains.kotlin.demo.Applicationkt'
    




sourceSets 
    main.java.srcDirs += 'src/main/kotlin/'
    test.java.srcDirs += 'src/test/kotlin/'


repositories 
    jcenter()


dependencies 
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // Required for Kotlin integration
    compile("org.springframework.boot:spring-boot-starter-web")

    compile group: 'org.apache.camel', name: 'camel-quartz2', version: '2.20.2'
    compile group: 'org.apache.camel', name: 'camel-http4', version: '2.20.2'
    compile group: 'org.apache.camel', name: 'camel-docker', version: '2.20.2'
    compile group: 'org.apache.camel', name: 'camel-aws', version: '2.20.2'

    testCompile('org.springframework.boot:spring-boot-starter-test')

【问题讨论】:

【参考方案1】:

Applicationkt 更改为 ApplicationKt 即可,顺便说一句,您可以将 Kotlin 版本升级为 1.3.50

Applicationkt 我指的是这一行中的那个:

attributes 'Main-Class': 'org.jetbrains.kotlin.demo.Applicationkt'

【讨论】:

【参考方案2】:

Kotlin 将 Application 文件编译成两个不同的文件:

一个名为 Application.class 的文件与 Springboot 相关 另一个名为 ApplicationKt.class 的文件带有 main 方法

在第二个文件中是 ma​​in 函数所在的位置,因此您必须在 build.gradle 文件中使用此名称。

mainClassName = 'org.jetbrains.kotlin.demo.ApplicationKt'

【讨论】:

【参考方案3】:

将你的 build.gradle 更新为

jar 
    manifest 
        attributes 'Main-Class': 'org.jetbrains.kotlin.demo.ApplicationKt'
    
    from  
        configurations.compile.collect  it.isDirectory() ? it : zipTree(it)  
    

在 ApplicationKt 中使用大写字母 K。

这是必需的,因为 Kotlin 编译为 Java 字节码的方式。 Kotlin 中的fun main() 函数不附属于任何类,但 Java 始终需要一个类并且不支持无类函数。

Kotlin 编译器必须创建一个 Java 类。因为您已经定义了一个类 Application,所以它为 Kotlin 文件 org/jetbrains/kotlin/demo/Application.kt 中的函数创建了一个后缀为 Kt 的类。您必须设置此类,以便 JVM 可以找到它。

顺便说一句,Jar 文件只是一个 Zip 文件,您可以将其解压缩并自己查看 ApplicationKt.class 是否存在。

【讨论】:

我认为前两段无关 更新答案以解释为什么 Kotlin 确实需要额外的 Kt 我把扩展改成 Kt 并且把 kotlin 版本升级到 1.2.31,但是没有运气。 @phisch 你可以自己尝试为上述项目构建一个带有附加依赖项的胖 jar。 我构建了一个“Hello World”示例,它按预期运行。请用更多信息更新您的问题,尤其是确切的错误消息、jar 文件的内容(是否有 ApplicationKt 类)等。谢谢。 @phisch 你运行 ./gradlew clean jar 命令了吗?之后你运行独立的 jar 文件?你可以试试上面的 github 存储库链接吗?【参考方案4】:

确实,如果您的主类文件名为 Application.kt,Kotlin 会在 jar 中创建文件 ApplicationKt.class。您必须添加以下行:

apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'org.jetbrains.kotlin.demo.ApplicationKt'

如果您使用经典的jar 插件,您可以执行以下操作(在之前的回复中有描述):

jar 
    manifest 
        attributes 'Main-Class': 'org.jetbrains.kotlin.demo.ApplicationKt'
    
    from  
        configurations.compile.collect  it.isDirectory() ? it : zipTree(it)  
    

但是,我更喜欢使用 bootJar 插件,它非常清晰,并且允许我使用分层 jar,例如:

bootJar 
    layered() // Not useful if you don't want to use layered jars

【讨论】:

【参考方案5】:

对我来说,主要功能需要在类主体之外

@SpringBootApplication
@Configuration
class Application
(private val locationRepository: LocationRepository,
) : CommandLineRunner 

    override fun run(vararg args: String?) 
        whatever()
    


fun main(args: Array<String>) 
    runApplication<Application>(*args)

【讨论】:

以上是关于Kotlin Gradle 无法找到或加载主类的主要内容,如果未能解决你的问题,请参考以下文章

Gradle(包装器)+ STS + Spring Boot:错误:无法找到或加载主类 1.1,

Flutter 收到错误“错误:无法找到或加载主类 org.gradle.wrapper.GradleWrapperMain”

React Native Android - 无法找到或加载主类 org.gradle.wrapper.GradleWrapperMain

如何修复“无法找到或加载主类 org.gradle.launcher.daemon.bootstrap.GradleDaemon”?

无法使用 gradle-jooq-plugin-3.0.1、jooq-3.11.2 找到或加载主类 org.jooq.codegen.GenerationTool

Spring Boot gradle“找不到或加载主类”