【问题标题】:Can't specify main manifest attribute in Intellij无法在 Intellij 中指定主要清单属性
【发布时间】:2018-09-25 09:55:18
【问题描述】:

我正在尝试为我一直在处理的 api 生成一个可执行 jar。我已经能够使用 localhost 在本地进行调试,但是当我尝试从命令行运行生成的 jar 工件时,我收到错误 no main manifest attribute, in api.jar。我已经阅读了相关的 SO 问题 herehere,但他们建议的更改似乎没有效果。我的项目结构如下:

当我在工件向导中导航时尝试选择主类时,我可以一直突出显示main 类,但“确定”按钮被禁用。

最后,当我尝试通过右键单击主类名称并选择 Copy Reference 并将剪贴板值粘贴到清单文件中手动指定主类时,我收到错误主类无效:

我的实际主要课程包括在下面。任何帮助表示赞赏。

package api

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication

@SpringBootApplication
open class KotlinSpringJpaPostgresqlApplication

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

最后,如果您想尝试在本地运行它,我的代码可以在here 获得。

【问题讨论】:

    标签: java spring-boot intellij-idea jar kotlin


    【解决方案1】:

    您需要将带有大写KKt 附加到包含您的主方法的文件名。这是必需的,因为 Kotlin 编译为 Java 字节码的方式。 Kotlin 中的fun main() 函数不附属于任何类,但 Java 始终需要类,不支持无类函数。

    请注意,文件名在这里很重要(在您的问题中是 api.kt)。我建议只创建一个文件Main.kt 并将您的主要功能移到那里。它将被编译成一个 MainKt 类,你应该从你的 Manifest 中引用它。

    我希望您手动创建的 MANIFEST.MF 文件会被构建过程覆盖。您是否解压了最终的 jar 文件并检查了 MANIFEST.MF 是否符合您的预期?

    与其自己编写 MANIFEST.MF,不如让您的构建系统为您处理:

    对于 Maven:

    <configuration>
        <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>api.KotlinSpringJpaPostgresqlApplicationKt</mainClass>
            </manifest>
        </archive>
    </configuration>
    

    对于 Gradle:

    jar {
         manifest {
            attributes 'Main-Class': 'api.KotlinSpringJpaPostgresqlApplicationKt'
        }
        from { 
            configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } 
        }
    }
    

    【讨论】:

    • 我在 pom 中指定了它,并使用 maven 包从命令行编译了 .jar 以进行良好的测量。我收到了错误Exception in thread "main" java.lang.ClassNotFoundException: api.KotlinSpringJpaPostgresqlApplication Kt at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    • 对不起,我注意到我的答案中的这个空格来自哪里。必须是一个字api.KotlinSpringJpaPostgresqlApplicationKtKt前面没有空格
    • 我认为这可能是一个错字并尝试了两种方式。结果相同。
    • 能否请您再次检查一下 MANIFEST.MF 是否确实包含正确的主类以及 api.KotlinSpringJpaPostgresqlApplicationKt 确实是 Jar 的一部分?
    • .pom 生成的 MANIFEST.MF 包含类 api.KotlinSpringJpaPostgresqlApplicationKt。检查时,jar 包含类 BOOT-INF/classes/api/KotlinSpringJpaPostgresqlApplication.class
    【解决方案2】:

    问题在于类的名称,因为 Kotlin 将创建一个带有 Kt 后缀的 Java 类。

    这意味着清单中的主类应该是:

    主类:api.KotlinSpringJpaPostgresqlApplicationKt

    【讨论】:

    • 这只会导致错误变为Error: Could not find or load main class api.KotlinSpringJpaPostgresqlApplicationKt
    • 你能在 pom.xml 而不是 IntelliJ 中指定主类吗?我昨天在 Gradle 中做了这个,你的主要课程绝对应该是带有“Kt”后缀的课程。见:stackoverflow.com/questions/37671510/…
    • 我在 pom 中指定了它,并使用 maven 包从命令行编译了 .jar 以获得良好的测量效果。我在 java.net.URLClassLoader.findClass(URLClassLoader.java:381) 处的线程“main”java.lang.ClassNotFoundException: api.KotlinSpringJpaPostgresqlApplicationKt 中收到错误异常
    猜你喜欢
    • 2015-03-14
    • 2019-05-18
    • 1970-01-01
    • 2012-08-29
    • 2016-10-13
    • 1970-01-01
    • 2022-12-23
    • 2018-06-17
    • 1970-01-01
    相关资源
    最近更新 更多