无法在 Intellij 中指定主要清单属性

Posted

技术标签:

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

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

当我在工件向导中导航时尝试选择主类时,我可以一直突出显示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 获得。

【问题讨论】:

【参考方案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”后缀的课程。见:***.com/questions/37671510/… 我在 pom 中指定了它,并使用 maven 包从命令行编译了 .jar 以获得良好的测量效果。我在 java.net.URLClassLoader.findClass(URLClassLoader.java:381) 处的线程“main”java.lang.ClassNotFoundException: api.KotlinSpringJpaPostgresqlApplicationKt 中收到错误异常

以上是关于无法在 Intellij 中指定主要清单属性的主要内容,如果未能解决你的问题,请参考以下文章

Intellij IDEA 无法识别 Maven 依赖项中指定的类

未找到应用程序依赖项清单 (...) 中指定的程序集

使用 Intellij 2016 创建 Jar - 没有主要清单属性

Microsoft vcredist在运行时使用的版本比清单中指定的版本高

在清单文件中指定意图操作的正确方法是啥?

如何在 HTML5 缓存清单中指定通配符以加载目录中的所有图像?