在 pom.xml 中为 Kotlin 中的 Spring Boot 项目指定 Main 类

Posted

技术标签:

【中文标题】在 pom.xml 中为 Kotlin 中的 Spring Boot 项目指定 Main 类【英文标题】:Specifying Main class in pom.xml for spring boot projects in Kotlin 【发布时间】:2019-12-25 11:40:04 【问题描述】:

我使用Kotlin 创建了一个Spring Boot 项目。我想创建一个包含所有依赖项的.jar 文件,以便我可以从命令行运行应用程序。主类的 FQCN 是:com.example.Application.kt。我的pom.xml 中有以下配置:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <mainClass>com.example.Application</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

应用程序无法开始抱怨找不到 mainClass。这是示例异常:

Exception in thread "main" java.lang.ClassNotFoundException: com.example.Application
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:93)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:46)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)

我错过了什么?

【问题讨论】:

【参考方案1】:

我只是想自己学习 Kotlin,但我怀疑您可能需要在类名末尾附加 Kt。例如:

<manifest>
    <mainClass>com.example.ApplicationKt</mainClass>
</manifest>

与 Spring 无关,我在尝试构建可执行 JAR 时遇到了这个问题。如果你解压你的JAR并查看class文件,相信你会找到ApplicationKt.class

如果是这样,这是因为您没有在类中定义 main 函数。在这种情况下,Kotlin 会生成一个属于您文件的 &lt;filename&gt;Kt.class 版本的静态方法。根据this SO answer:

与 Java 不同,Kotlin 允许您定义不在类中的函数。但是如果你想让 Java 与 Kotlin 对话,这就成了一个问题。如何解决?将这些函数转换为名为“Kt”后缀的文件的类的静态方法

您可以在文档中找到更多相关信息

【讨论】:

【参考方案2】:

与其他答案类似,我使用 Spring Boot 2.4.2 和 Maven 进行了此操作

pom.xml

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <mainClass>demoapi.DemoApiApplicationKt</mainClass>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
    </execution>
  </executions>
</plugin>

DemoApiApplicationKt

package demoapi

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class DemoApiApplication

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

【讨论】:

你是对的。需要添加 kt 作为 Miles_Dowe 建议的答案。我忘记了我曾经问过这个问题。您的回答提醒我接受 Miles_Dowe 的原始回答【参考方案3】:

很可能与异常状态完全一样:您在包com.example 中缺少一个类Application,该类具有一个带有main 方法的伴随对象。

package com.example

import org.springframework.boot.ApplicationArguments
import org.springframework.boot.ApplicationRunner
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.Configuration

@SpringBootApplication
@Configuration
open class Application : ApplicationRunner 
    override fun run(args: ApplicationArguments) 
    

    companion object 
        @JvmStatic
        fun main(args: Array<String>) 
            SpringApplication.run(Application::class.java, *args)
        
    

【讨论】:

试过了,但没用。我理解黑客。事实上,您不需要@SpringBootApplication,只需要@Configuration@ComponentScan。但是,对于较新版本的 Spring BootKotlin,不再需要此 hack。问题仍然存在 - 它不起作用 :`(【参考方案4】:

遇到同样的错误。就我而言,我的主应用程序位于与src/main//kotlin 不同的路径中。在build 标记下的sourceDirectory 标记中指定该确切路径解决了我的问题。话虽如此,您还需要附加Kt 以使您的应用程序类ApplicationKt。下面是我的 pom.xml 的结构:

<build>
    <sourceDirectory>$project.basedir/src/generated-source/kotlin</sourceDirectory>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
    <mainClass>com.example.ApplicationKt</mainClass>
</configuration>
<executions>
    <execution>
        <goals>
            <goal>repackage</goal>
        </goals>
    </execution>
</executions>

【讨论】:

就我而言,如果我没记错的话,即使使用默认结构也会弹出错误。

以上是关于在 pom.xml 中为 Kotlin 中的 Spring Boot 项目指定 Main 类的主要内容,如果未能解决你的问题,请参考以下文章

Spring Initializr 生成的 pom.xml 中的错误

在 pom.xml 依赖标记中为 jar 文件添加 systemPath

Vaadin 20 入门项目在 pom.xml 中有错误

在 pom.xml 中对变量进行子字符串化

如何在 IntelliJ IDEA 14 中为当前项目工作配置注释处理?

pom.xml 每次添加新依赖时都会出错