Kotlin Gradle не удалось найти или загрузить основной класс

Я попытался скопировать образец проекта Spring Boot Kotlin https://github.com/JetBrains/kotlin-examples/tree/master/tutorials/spring-boot-restful. Я добавил еще несколько зависимостей, и когда я попытался создать исполняемую банку и запустить ее, я получил ошибку:

Не удалось найти или загрузить основной класс ...

Скрипт сборки 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')
}

person dks551    schedule 03.04.2018    source источник


Ответы (4)


Измените Applicationkt на ApplicationKt, и вы, кстати, можете обновить версию Kotlin до 1.3.50.

Под Applicationkt я имею в виду тот, что в этой строке:

attributes 'Main-Class': 'org.jetbrains.kotlin.demo.Applicationkt'
person ice1000    schedule 03.04.2018

Kotlin компилирует файл приложения в два разных файла:

  • один файл под названием Application.class с элементами Springboot
  • другой файл с именем ApplicationKt.class с основным методом

Во втором файле находится функция main, поэтому вы должны использовать это имя в файле build.gradle.

mainClassName = 'org.jetbrains.kotlin.demo.Application Kt'

person Antonio Martin    schedule 28.02.2019

Обновите свой build.gradle до

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

с заглавной буквой K в ApplicationKt.

Это необходимо из-за того, как Kotlin компилируется в байт-код Java. Функция fun main() в Kotlin не привязана к какому-либо классу, но Java всегда требует класса и не поддерживает бесклассовые функции.

Компилятор Kotlin должен создать класс Java. Поскольку вы уже определили класс Application, он создал класс с суффиксом Kt для функций в вашем файле Kotlin org/jetbrains/kotlin/demo/Application.kt. Вы должны установить этот класс, чтобы JVM могла его найти.

Кстати, файл Jar - это просто Zip-файл, вы можете распаковать его и сами убедиться, есть ли там ApplicationKt.class.

person phisch    schedule 03.04.2018
comment
Я думаю, что первые два абзаца не связаны - person ice1000; 03.04.2018
comment
Обновите ответ, чтобы объяснить, почему Kotlin требует дополнительных Kt - person phisch; 03.04.2018
comment
Я изменил расширения на Kt, а также обновил версию kotlin до 1.2.31, но безуспешно. @phisch Можете ли вы сами попробовать собрать толстую банку для вышеуказанного проекта с дополнительными зависимостями. - person dks551; 03.04.2018
comment
Я создал пример «Hello World», и он работает, как ожидалось. Пожалуйста, обновите свой вопрос дополнительной информацией, особенно точным сообщением об ошибке, содержимым вашего jar-файла (есть ли класс ApplicationKt) и т. Д. Спасибо. - person phisch; 03.04.2018
comment
@phisch Вы запускали команду ./gradlew clean jar? И после этого запускаете автономный файл jar? Можете ли вы попробовать по указанной выше ссылке на репозиторий github? - person dks551; 03.04.2018
comment
Да, я это сделал, и запускаются приложения весенней загрузки. Однако мой build.gradle немного отличается, см. Обновленный ответ. Нам понадобится от вас более подробная информация (см. Мой предыдущий пост), чтобы помочь вам. Спасибо. - person phisch; 03.04.2018
comment
Были ли у вас какие-то успехи или есть еще открытые вопросы? - person phisch; 17.04.2018

Действительно, Kotlin создает файл ApplicationKt.class в банке, если ваш основной файл класса называется Application.kt. Вам необходимо добавить следующие строки:

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, который очень понятен и позволяет, например, использовать многоуровневые банки:

bootJar {
    layered() // Not useful if you don't want to use layered jars
}
person veben    schedule 13.07.2020