spring - IntelliJ Idea 2017.3 无法启动 Kotlin Spring Boot 应用程序 - @Configuration 类可能不是最终的

标签 spring spring-boot gradle intellij-idea kotlin

我能够从 IntelliJ 2017.3 启动 Spring Boot Kotlin 应用程序。上次 IntelliJ 修复更新后,我无法从 IDE 启动该应用程序,出现此异常:

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

我可以像往常一样从终端启动它:java -jar xxxx.jar

这没有任何意义,因为我在 Gradle 配置中使用了必要的 Kotlin Spring 插件:

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'
}

有什么想法吗?

更新:

一种更简单的重现方法,只需使用 IntelliJ 的 Spring 初始化程序创建一个 Spring Boot 项目,您将看到相同的结果:

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')
}

最佳答案

首先,这一切都归功于 Kotlin 类 class definition :

The open annotation on a class is the opposite of Java's final: it allows others to inherit from this class. By default, all classes in Kotlin are final

所以如果你可以随意修改你的源代码,你可以让你的类不是最终的,只需添加 open其签名如下:

@SpringBootApplication
open class DemoApplication

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

或根据此 article 的可能解决方案之一:

The @SpringBootApplication is a convenience annotation that marks the class with the @Configuration, @EnableAutoConfiguration and @ComponentScan annotations. It is the @Configuration annotation that forces the use of the open keyword.

是尝试删除@SpringBootApplication@EnableAutoConfiguration 注释和注释你的类和 @ComponentScan来解决这个问题。

关于spring - IntelliJ Idea 2017.3 无法启动 Kotlin Spring Boot 应用程序 - @Configuration 类可能不是最终的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48544015/

相关文章:

spring - 如何使用 Spring + DBUnit + JUnit 配置多个事务管理器

java - 无法提取响应 : no suitable HttpMessageConverter found for response type class and content type [text/html]

gradle - Kotlin buildscript不使用我的自定义Maven repo

android - Buck - 构建具有多种 Gradle 风格/构建类型和 list 的 Android 应用程序

java - 使用 Spring,如何获取具有特定实例的类的列表?

java - 如何让嵌入式mongodb在应用程序关闭时保留数据?

java - 如何在启动 spring 时选择性地加载 bean

java - Spring引导+Spring数据jpa : how do I know if adding data to table failed due to duplicate primary key?

spring-boot - 当 Spring Boot 应用程序启动时,JSR-303 注释不会验证 bean 属性

gradle - 根目录build.gradle很大。这些通常通过什么方法分解?