Подтвердить что ты не робот

IntelliJ Idea 2017.3 не может запустить Kotlin Spring Boot App - класс @Configuration может быть не окончательным

Я смог запустить приложение Spring Boot Kotlin от IntelliJ 2017.3. После последнего обновления исправления IntelliJ я не могу запустить это приложение из среды IDE, получив это исключение:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: @Configuration class 'AccessConfig' may not be final

Я могу запустить его с терминала, как обычно: java -jar xxxx.jar

Это не имеет никакого смысла, поскольку я использую необходимый плагин Kotlin Spring в моей конфигурации Gradle:

buildscript {
    ext {
        kotlinVersion = '1.2.21'
        springBootVersion = '2.0.0.RC1'
    }
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
        jcenter()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
        classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
        classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.2'
        classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.5"
    }
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'maven'
...
sourceCompatibility = 1.8
compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

repositories {
    mavenLocal()
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
    maven { url "http://repo.maven.apache.org/maven2" }
    maven { url 'https://jitpack.io' }
}

ext {
    springCloudVersion = 'Finchley.M5'
    mmaReleaseTrainVersion = 'Callao-SNAPSHOT'
    junitVersion = '5.0.2'
}

Любые идеи?

UPDATE:

Простейший способ воспроизведения, просто создайте проект загрузки Spring с инициализатором Spring от IntelliJ, вы увидите тот же результат:

DemoApplication:

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    SpringApplication.run(DemoApplication::class.java, *args)
}

Ошибка:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: @Configuration class 'DemoApplication' may not be final. Remove the final modifier to continue.
Offending resource: com.example.demo.DemoApplication

build.gradle:

buildscript {
    ext {
        kotlinVersion = '1.2.10'
        springBootVersion = '1.5.10.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
        classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
    }
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compile("org.jetbrains.kotlin:kotlin-stdlib-jre8:${kotlinVersion}")
    compile("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
    testCompile('org.springframework.boot:spring-boot-starter-test')
}
4b9b3361

Ответ 2

Прежде всего, все из-за класса Kotlin определения класса:

Аннотация open для класса является противоположностью Java final: она позволяет другим наследовать от этого класса. По умолчанию все классы в Котлине являются окончательными

поэтому, если вы можете свободно изменять свой исходный код, вы можете сделать свой класс не окончательным, просто добавив open к нему подпись следующим образом:

@SpringBootApplication
open class DemoApplication

fun main(args: Array<String>) {
    SpringApplication.run(DemoApplication::class.java, *args)
}

или одно из возможных решений, в соответствии с этой статьей:

@SpringBootApplication - это удобная аннотация, которая помечает класс аннотациями @Configuration, @EnableAutoConfiguration и @ComponentScan. Это аннотация @Configuration заставляет использовать ключевое слово open.

Это попытка удалить аннотацию @SpringBootApplication и аннотировать ваш класс с помощью @EnableAutoConfiguration и @ComponentScan, чтобы решить эту проблему.

Ответ 3

Если обновление плагинов не помогает, проверьте, соответствует ли версия kotlin в gradle идее kotlin версии.

Ответ 4

Если вы получаете эту ошибку на IntelliJ, даже с плагином kotlin-spring, вы можете проверить, включена ли обработка аннотаций в IntelliJ.