在创建IntelliJ IDEA的.jar文件时,Manifest.mf文件出错。

107

我正在尝试将使用OptaPlanner 6.0.1库的项目通过IntelliJ IDEA的jar构件打包成一个.jar文件,但是我的manifest.mf文件并不包含标准内容。

Manifest-Version: 1.0
Main-Class: a.b.c.app

该jar使用ecj-3.7.2.jar中提供的一个,这是OptaPlanner的支持库之一:

Manifest-Version: 1.0
Build-Jdk: 1.6.0_26
Built-By: ibrandt
Created-By: Apache Maven
Archiver-Version: Plexus Archiver

因此,当尝试运行应用程序时,会出现"no main manifest attribute, in appname.jar"错误。如果我手动用我的清单替换.jar文件中的清单,则一切都可以正常工作。有什么方法可以解决这个问题吗?

我将库保存在一个单独的/lib目录中,并将它们作为提取的目录添加到jar构件的根目录下,使用的是IntelliJ IDEA v13.0.1。


1
你知道像ant、maven或gradle这样的构建工具吗? - MariuszS
我知道它们,但到目前为止我只使用过make和.NET的对应工具(NAnt,MSBuild)。如果IntelliJ的构建工具不够用,我应该选择哪一个? - grudolf
1
在这里投票以纠正此问题 here - bigjosh
8个回答

274

我遇到了同样的问题。

请确保你的 MANIFEST.MF 文件位于:

src/main/resources/META_INF/

不是

src/main/java/META_INF/

20
确实,这是正确的答案,看起来Intellij IDEA在使用Maven项目模板时会出现META-INF文件夹错位的问题。 - Kumait
在我的情况下,我不得不更改项目的布局。我之前有一个使用Maven布局的项目,但我删除了对Maven的支持。我从头开始重新创建了一个项目,现在它可以正常工作了。 - Maxence
1
这对我不起作用,我不得不将Mainfest文件移动到项目的根目录。 - racs
Maven难道真的会把这个文件放到错误的目录下吗? :^) - Daria
@Kumait,这个问题在IntelliJ 2017.1.5中仍然存在。我想知道JetBrains团队是否意识到了这个问题。 - fruqi
我不知道我的IntelliJI IDEA 2017.2.6出了什么问题。但是在我的/resources文件夹中也出现了问题。将其保留为src/META_INF/对我有用。 - Abhishek Saini

13

解决方法:

  1. 文件 > 项目结构
  2. 在左侧的 项目设置 中选择 "Artifacts"
  3. 在中间的面板中找到 JAR 定义并选择它
  4. 在 "输出布局" 选项卡的左侧面板中查找列表中的 JAR 文件并选择它
  5. 在底部,点击 "使用现有清单" 按钮,并选择你的项目源代码中的清单文件。
  6. 点击确定并运行构建

6
没有“使用现有清单”按钮,但是输出布局中的清单文件指向正确位置(...\src\main\java\META-INF\MANIFEST.MF)。 - grudolf
7
好的,我需要删除jar文件并重新创建它,这次创建的时候需要使用“Empty”而不是“From modules with dependencies”。这样就会出现“Create Manifest”和“Use Existing Manifest”两个按钮,然后指向我的清单文件并重新添加库和编译输出。与之前有两个不同之处:现在显式包含了META-INF\MANIFEST.INF在输出布局中,并且似乎正确生成了jar文件。 :) - grudolf
这个并没有解决问题,至少对我来说是这样。不过,jamahn的回答确实有效。 - Andrew Breksa
低声望用户@ds-justice添加了以下评论-在经过几个小时的努力后,@grudolf上面关于创建一个空Jar的评论是唯一有效的方法,我一直在处理导入的Gradle项目。这是一个重要的问题,请考虑将您的评论重新发布为单独的答案。 - Shawn Mehan

12

正如在其他答案的@grudolf评论中所提到的,一种方法是创建一个空的jar文件(这也是我在导入Gradle项目时唯一有效的方法):

  • Project Structure -> Artifacts -> + Jar -> Empty
  • 中央面板现在有创建清单和使用现有清单按钮。 使用其中之一。
  • 如果将具有自己清单的依赖库提取到输出根目录中,我会遇到麻烦,它们似乎会间歇性地覆盖新手动创建的清单。 尝试更改操作顺序似乎可以使其正常工作。

更新:

这绝对是Idea中的一个错误。此链接中的回答在存在提取的目录时可以可靠地工作。 实质上,您可以找到您的.idea/JARNAME.xml,并将以下元素添加到非常顶部<root>元素中以获取您的jar。 任何包含清单的上面的提取元素都将覆盖您的新清单。

  <element id="directory" name="/META-INF">
    <element id="file-copy" path="$PROJECT_DIR$/modulename/src/META-INF/MANIFEST.MF" />
  </element>

7

如果您想指定主类,您需要将此插件添加到pom.xml文件中:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>Form</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

1
我遇到了类似的问题。 问题出在pom.xml文件中。
<archive>
  <manifestEntries>
    <Dependencies>one.jar,
                  two.rar, 
                  other.jar
    </Dependencies>
  </manifestEntries>
</archive>

我不知道为什么这段代码在Eclipse中可以运行,但在IntelliJ中却不能运行。
这是正确的。
<archive>
  <manifestEntries>
    <Dependencies>one.jar, two.rar, other.jar</Dependencies>
  </manifestEntries>
</archive>

Manifest.mf工作了!!!

希望这能帮到你。


我曾经遇到过这种情况,得出了与您相同的结论:在Eclipse中,在<Dependencies>项之间换行可行,但在Intellij IDEA中不起作用。 - Arion Krause

0

生成可执行的jar包有几种方法。使用IntelliJ的GUI功能是一种好的方式。另一种方法是使用Maven(或类似的gradle、buildr等),这是构建服务器友好的:

它基本上可以从optaplanner示例maven构建中复制粘贴:

  1. 最终用户的jar包(optaplanner-examples-*.jar)必须在其清单文件中包含其依赖项的类路径
  2. 然后sh和bat脚本必须相应地运行该jar包。

0
请按照此处详细说明的步骤进行操作。

https://www.jetbrains.com/help/idea/2022.2/convert-a-regular-project-into-a-maven-project.html#develop_with_maven

点击“构建项目”图标以构建项目。IntelliJ IDEA 会生成目标文件夹。请注意,IntelliJ IDEA 只编译源代码,不会创建 JAR 文件或清单文件。 在资源目录中创建一个清单文件。
右键单击该目录,选择“新建 | 目录”以创建 META-INF 子目录。然后右键单击子目录,选择“新建 | 文件”以创建 MANIFEST.MF 文件。
打开 MANIFEST.MF 文件并添加有关您的主类的信息。
检查以下代码:
Main-Class: com.company.MyApp 或者,我们可以要求 Maven 使用以下代码将此行代码添加到 MANIFEST.MF 文件中:
org.apache.maven.plugins maven-jar-plugin com.company.MyApp 在 POM 中指定清单文件信息,这样您就可以使用 Maven 生成可执行的 JAR 文件。
带有清单的 POM。或者,您可以执行“package”而不是“install”命令来实现相同的结果。

0
要避免像清单(Manifest)这样的问题,你应该在“src”目录下创建一个名为“META-INF”的文件夹。因此,请创建该文件夹,并在其中放置一个名为“MANIFEST.MF”的文件,其内容如下:
Manifest-Version: 1.0
Main-Class: <packageName>.Main

别忘了替换上面包含主类的包名!


6
记录显示,我在八月份从你的帖子中删除了宗教内容。请注意,社区已经讨论过是否将宗教主题添加到帖子中,答案是我们更愿意将它们省略掉。不过,你可以随意在个人资料或头像中添加宗教内容。 - halfer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接