关于Java:不能执行jar文件:”没有主清单属性”no main manifest attribute

Can't execute jar- file: “no main manifest attribute”

我安装了一个应用程序,当我试图运行它时(它是一个可执行的JAR),什么都没有发生。当我从命令行运行它时:

java -jar"app.jar"

我收到以下信息:

no main manifest attribute, in"app.jar"

通常,如果我自己创建了程序,我会向清单文件添加一个主类属性。但在本例中,由于文件来自应用程序,所以我不能这样做。我还尝试提取jar来查看是否可以找到主类,但是对于许多类来说,没有一个类的名称中包含单词"main"。必须有一种方法来解决这个问题,因为程序在其他系统上运行良好。


首先,看到你运行java -jar"app"而不是java -jar app.jar,有点奇怪。

第二,要使JAR可执行…您需要jar一个名为META-INF/manifest.mf的文件

文件本身应该(至少)有一个行程序:

1
Main-Class: com.mypackage.MyClass

其中com.mypackage.MyClass是持有公共静态void main(string[]args)入口点的类。

请注意,有几种方法可以通过CLI、Maven、Ant或Gradle实现这一点:

对于CLI,以下命令将执行:(tks@dvrt)
jar cmvf META-INF/MANIFEST.MF .jar

对于Maven来说,下面的代码片段应该可以做到这一点。请注意,这只是插件定义,而不是完整的pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<build>
  <plugins>
    <plugin>
      <!-- Build an executable JAR -->
      <groupId>org.apache.maven.plugins</groupId>
      maven-jar-plugin</artifactId>
      <version>3.1.0</version>
      <configuration>
       
          <manifest>
            true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>com.mypackage.MyClass</mainClass>
          </manifest>
        </archive>
      </configuration>
    </plugin>
  </plugins>
</build>

(选择适合您的项目的。)

对于Ant,下面的代码片段应该有帮助:

1
2
3
4
5
6
7
<jar destfile="build/main/checksites.jar">
  <fileset dir="build/main/classes"/>
  <zipfileset includes="**/*.class" src="lib/main/some.jar"/>
  <manifest>
   
  </manifest>
</jar>

迈克尔·尼曼-

Gradle:

1
2
3
4
5
6
7
8
9
10
11
plugins {
    id 'java'
}

jar {
    manifest {
        attributes(
                'Main-Class': 'com.mypackage.MyClass'
        )
    }
}


应该是java -jar app.jar,而不是java -jar"app"

-jar选项仅在jar文件是可执行jar文件时有效,这意味着它必须有一个清单文件,其中包含Main-Class属性。请参见在JAR文件中打包程序以了解如何创建可执行JAR。

如果它不是一个可执行的JAR,那么您需要用如下代码运行该程序:

1
java -cp app.jar com.somepackage.SomeClass

其中com.somepackage.SomeClass是包含运行程序的main方法的类。(那门课的内容取决于程序,从你提供的信息中是不可能分辨出来的)。


或者,您可以使用maven程序集插件,如下例所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<plugin>
    maven-assembly-plugin</artifactId>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
     
        <manifest>
          true</addClasspath>
          <mainClass>com.package.MainClass</mainClass>
        </manifest>
      </archive>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

在本例中,第节中指定的所有依赖jar将自动包含在单个jar中。请注意,带有依赖项的JAR应该按照字面意思放在一起,而不是替换为要包含的JAR文件名。


这是因为Java无法在声明.MF文件中找到主要属性。要告诉Java应该使用哪个类作为应用程序的入口点,主要属性是必需的。在JAR文件中,manifest.mf文件位于META-INF文件夹中。想知道如何查看JAR文件中的内容?用winrar打开jar文件。

manifest.mf中的主要属性如下:

1
Main-Class: <packagename>.<classname>

当manifest.mf文件中缺少此行时,会出现此"无主清单属性"错误。

在manifest.mf文件中指定此属性真是一团糟。

更新:我刚刚找到了一种在Eclipse中指定应用程序入口点的非常好的方法。当你说出口,

1
2
3
4
5
6
7
8
9
Select Jar and next

[ give it a name in the next window ] and next

and next again

and you'll see" Select the class of the application entry point".

Just pick a class and Eclipse will automatically build a cool MANIFEST.MF for you.

enter image description here


Gradle的答案是添加一个jar/manifest/attributes设置,如下所示:

1
2
3
4
5
6
7
apply plugin: 'java'

jar {
    manifest {
        attributes 'Main-Class': 'com.package.app.Class'
    }
}


尝试使用此命令包含jar:

1
java -cp yourJarName.jar your.package..your.MainClass


对于Maven,这就是解决这个问题的方法(对于我来说,对于基于Github的Veetle代码库):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<build>
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    maven-shade-plugin</artifactId>
    <version>2.0</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
              <mainClass>org.lazydevs.veetle.api.VeetleAPI</mainClass>
            </transformer>
          </transformers>
        </configuration>
      </execution>
    </executions>
  </plugin>
 </plugins>
</build>

干杯。。。


我在使用intellij思想创建jar时遇到了这个问题。请参阅此讨论。

解决这个问题的方法是重新创建JAR工件,从依赖模块中选择JAR>,但不接受META-INF/manifest.mf的默认目录。将它从-/SRC/Ma/Java转换为-/SRC/main/资源。

否则,它在jar中包含一个清单文件,而不是它在//SRC/Ma/Java中的一个文件。


我也有同样的问题。通过在pom文件中添加以下行,使其正常工作。该插件将确保您的应用程序的构建过程和所有必要的步骤。

1
2
3
4
5
6
7
8
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>


对我来说,所有的答案都没有真正的帮助——我把清单文件放在了正确的位置,包含了主类和所有的东西。让我吃惊的是:

Warning: The text file from which you are creating the manifest must
end with a new line or carriage return. The last line will not be
parsed properly if it does not end with a new line or carriage return.

(来源)。在清单末尾添加新行修复了它。


我刚才也犯了同样的错误。如果你使用的是gradle,只需在gradle.build中添加下一个:

1
2
3
4
5
6
7
apply plugin: 'java'

jar {
    manifest {
        attributes 'Main-Class': 'com.company.project.MainClass'
    }
}

其中,com.company.project.MainClass使用public static void main(String[] args)方法指向ur类的路径。


如果使用maven,请在pom中包含以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<parent>
    <groupId>org.springframework.boot</groupId>
    spring-boot-starter-parent</artifactId>
    <version>1.4.2.RELEASE</version>
</parent>

<properties>
    <java.version>1.8</java.version>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>


我今天也有同样的问题。我的问题解决了,我把META-INF移到资源文件夹。


我也面临同样的问题,现在已经解决了:)只需遵循下面的步骤,错误可能是针对任何事情的,但是下面的步骤会使过程更平滑。我花了很多时间来寻找解决方法。

1.尝试重新启动Eclipse(如果使用Eclipse构建JAR文件)实际上,这有助于我正确导出JAR文件。

2、在Eclipse重新启动之后,尝试查看您的Eclipse是否能够通过Java项目识别主类/方法->右击- >运行为->运行配置->"主键">单击"搜索"按钮,以查看您的Eclipse是否能够在JAR文件中查找主类。-->这是为了验证JAR文件是否具有指向主类的入口点。

  • 在此之后,将Java动态项目导出为"Runnabl jar"文件,而不是JAR文件。

  • 在Java启动配置中,选择主类。

  • 导出JAR文件后,使用下面的命令执行。Java-CP [您的jar ] .jar(完整包)。例如:Java-CPApPultRuleAudiT.JAR COM.Apple

  • 您可能会面临不受支持的Java版本错误。解决方案是在shell BASH配置文件中更改JavaAHEAD,以匹配用于在Eclipse中编译项目的Java版本。

  • 希望这有帮助!如果你还有什么问题,请告诉我。


    如果jar不遵循规则,则它不是可执行jar。


    您可能没有正确创建JAR文件:

    ex: missing option m in jar creation

    以下工作:

    1
    jar -cvfm MyJar.jar Manifest.txt *.class

    我个人认为这里所有的答案都是对这个问题的误解。答案在于Spring引导如何构建.jar。每个人都知道SpringBoot设置了这样一个清单,这与每个人的假设不同,即这是一个标准的.jar启动,它可能是,也可能不是:

    1
    2
    3
    4
    5
    6
    7
    Start-Class: com.myco.eventlogging.MyService
    Spring-Boot-Classes: BOOT-INF/classes/
    Spring-Boot-Lib: BOOT-INF/lib/
    Spring-Boot-Version: 1.4.0.RELEASE
    Created-By: Apache Maven 3.3.9
    Build-Jdk: 1.8.0_131
    Main-Class: org.springframework.boot.loader.JarLauncher

    也许它需要在类路径上与org.springframework.boot.loader.JarLauncher一起执行?


    任何可执行JAR文件都应该通过使用JavaJAR App.jar命令提示符来单击或运行(使用"jar包含路径的IF路径",即Java-jar)c:文件夹名App.jar)。如果可执行JAR没有运行,这意味着它没有正确创建。

    为了更好地理解,提取JAR文件(或使用任何工具查看,对于Windows7-Zip是一个不错的工具),并检查/META-INF/manifest.mf下的文件。如果你找到类似的条目

    主类:your.package.name.claasWithMain-那没关系,否则你必须提供它。

    注意在manifest.mf文件中附加主类条目,检查您将其保存在哪里!


    对于我来说,这个错误仅仅是因为我忘记告诉Eclipse我想要一个可运行的JAR文件,而不是一个简单的库JAR文件。因此,当您在Eclipse中创建JAR文件时,请确保您单击了右边的单选按钮。


    你只需按照这个步骤使用创建JAR文件

    1
     jar -cfm jarfile-name manifest-filename Class-file name

    运行jar文件时,简单地运行如下

    1
     java -cp jarfile-name main-classname

    我找到了一个新的解决方案,坏的清单生成!

  • 使用类似winrar的zip编辑器打开jar文件
  • 点击META-INF

  • 添加或编辑

    • 添加:

      • 在名为META-INF的文件夹中创建名为manifest.mf的文本文件并添加以下行:

        • 清单版本:1.0
        • 主类:package.ex.com.views.mainClassName
      • 保存文件并将其添加到zip

    • 编辑:

      • 将文件拖出修改manifest.mf以添加上一行
  • 打开CMD和类型:Java-jar C:/PATH/JARNAME.jar

  • 现在应该可以了!


    我也有同样的问题。这里提到的很多解决方案并没有给我完整的描述,所以我将尝试给您一个如何从命令行打包JAR文件的摘要。

  • 如果您希望在包中包含您的.class文件,请在.java的开头添加该包。

    爪哇

    1
    2
    3
    4
    5
    6
    package testpackage;

    public class Test
    {
        ...
    }
  • 要使用以包名称给出的结构结尾的.class文件编译代码,请使用:

    1
    javac -d . Test.java

    -d .使编译器创建所需的目录结构。

  • 打包.jar文件时,需要指示jar例程如何打包。这里我们使用选项集cvfeP。这是为了保持包结构(选项P),指定入口点,以便清单文件包含有意义的信息(选项e)。选项f允许您指定文件名,选项c创建存档,选项v将输出设置为verbose。这里需要注意的重要事情是Pe

    然后我们要的罐子的名字出现了。

    然后是入口点。

    然后来-C . /从该文件夹中获取类文件,保留文件夹结构。

    1
    jar cvfeP test.jar testpackage.Test -C . testpackage/
  • 在zip程序中检查您的.jar文件。它应该具有以下结构

    试验罐

    1
    2
    3
    4
    META-INF
    | MANIFEST.MF
    testpackage
    | Test.class

    manifest.mf应包含以下内容

    1
    2
    3
    Manifest-Version: 1.0
    Created-By: <JDK Version> (Oracle Corporation)
    Main-Class: testpackage.Test

    如果用手工编辑清单,请务必在末尾保留换行符,否则Java无法识别它。

  • 使用

    1
    java -jar test.jar

  • 既然您已经添加了manifest.mf,我认为您应该考虑这个文件中字段的顺序。我的env是java version"1.8.0_91"

    和我的舱单一样。

    1
    2
    3
    4
    5
    6
    7
    8
    // MANIFEST.MF
    Manifest-Version: 1.0
    Created-By: 1.8.0_91 (Oracle Corporation)
    Main-Class: HelloWorldSwing

    // run
    ~ java -jar HelloWorldSwing.jar
    no main manifest attribute, in HelloWorldSwing.jar

    然而,这是如下运行

    1
    2
    3
    4
    5
    Manifest-Version: 1.0
    Main-Class: HelloWorldSwing
    Created-By: 1.8.0_91 (Oracle Corporation)

    //this run swing normally


    以上的回答对我只有部分帮助。java -cp是答案的一部分,但我需要关于如何识别要运行的类的更具体的信息。以下是我的工作:

    第1步:找到我需要运行的类

    1
    jar tf /path/to/myjar.jar | more

    结果的顶行是:

    1
    2
    3
    4
    5
    6
    META-INF/
    META-INF/MANIFEST.MF
    somepath/
    somepath/App.class
    META-INF/maven/
    ...

    app.class包含要运行的主类。我不能百分之百地确定你是否可以一直假设你需要的是第一个班级,但它是为我准备的。如果不是这样,我想使用grep排除与库相关的结果来将类列表缩减到可管理的大小并不难。

    从那里很容易:我只使用了那个路径(减去".class"后缀):

    1
    java -cp /path/to/myjar.jar somepath/App


    (第一个岗位-所以可能不干净)

    这是我对OS X 11.6的修复,基于Maven的NetBeans 8.2程序。到目前为止,我的应用程序是100%的NetBeans——没有任何调整(只是一些外壳逃逸的不可能!).

    在尝试了这里和其他地方的大多数答案之后,我回到了"使用什么作品"的艺术。

    这里的最佳答案(奥利维尔·雷法洛·桑克斯)看起来是正确的开始,但没有帮助。

    在查看其他确实有效的项目时,我注意到了清单行中的一些细微差异:

  • AddClassPath、ClassPathPrefix不存在(已删除)
  • mainClass缺少"com"。(使用了nb->project属性->运行->主类->浏览以指定)
  • 不知道为什么(我只有3个月的Java)或如何,但只能说这是有效的。

    这里只使用了修改后的清单块:

    1
    2
    3
        <manifest>
            <mainClass>mypackage.MyClass</mainClass>
        </manifest>

    我遇到了这个问题,最近在NetBeans 8中解决了这个问题(请参阅下图):

    Netbeans project properties

  • 转到项目的属性。
  • 点击运行。
  • 使用"浏览"指定项目的主类。
  • 构建并运行JAR文件。

  • 只是想说清楚一点

    1
    Main-Class: <packagename>.<classname>

    如果没有包,则必须忽略该部分,如下所示:

    1
    Main-Class: <classname>


    你可能和我有同样的问题。创建.jar文件后,写入jar xf app.jar META-INF/MANIFEST.MF。这将创建文件到当前目录的副本,以便您可以读取该文件。如果只是说:

    Manifest-Version: 1.0

    Created-By: 1.8.0_51 (Oracle Corporation)

    并且不包含"主类"声明,那么我认为你发现了你的问题。

    不过,我不知道如何解决这个问题。我检查了StackOverflow上有相同/相似问题的其他人,但没有找到答案。然而,有了这些信息,你可能会得到更好的帮助(考虑到你和我有同样的问题)。

    编辑:我尝试过一个清单文件,但没有使其工作,但我的错误是在创建JAR文件时只命名其中一个类。我改为写了*.class,现在它工作了。

    尽管我不知道为什么需要创建清单文件。但我想只要它有效就可以了。


    如果您使用命令行来组装.jar,那么可以指向main而不添加清单文件。例子:

    1
    jar cfve app.jar TheNameOfClassWithMainMethod *.class

    (参数"e"是这样做的:TheNameOfClassWithMainMethod是方法main()和app.jar的类名称-可执行文件的名称.jar和*.class-只是所有要组装的类文件)


    检查manifest.mf主类中的jar文件是否可用

    第一、爪哇

    1
    2
    3
    4
    5
    6
    7
    class first
    {
            public static void main (String arg[ ])
            {
               System.out.println("Welcome to the world of Java");
            }
    }

    之前:

    1
    2
    3
    4
    5
    Manifest-Version: 1.0
    Created-By: 1.7.0_80 (Oracle Corporation)

    sony@sony-VPCEH25EN:~/Documents$ java -jar first.jar
    no main manifest attribute, in first.jar

    后:

    1
    2
    3
    4
    5
    6
    Manifest-Version: 1.0
    Created-By: 1.7.0_80 (Oracle Corporation)
    Main-Class: first

    sony@sony-VPCEH25EN:~/Documents$ java -jar first.jar
    Welcome to the world of Java

    我和你有一个相似的问题,以下是成功创建.war文件的语法:

    JAR CVF[JAR文件][清单文件]

    manifest
    When creating (c) or updating (u) a JAR file, the manifest operand defines the preexisting manifest files with names and values of attributes to be included in MANIFEST.MF in the JAR file. The manifest operand must be specified if the f option is present '[1]'.

    为了创建清单文件,需要为某些属性定义一个值,可以在(.war)文件名后面加上星号以避免创建清单文件:

    JAR-CVF foo.war公司*

    老实说,我不知道这是否是一个最佳实践,但它确实为我工作。


    找到一个很好的解决方案,在任何这样的情况下都会有所帮助,因为您只需要一个可运行的jar,在大多数情况下都是这样做的。如果应用程序运行在Intellij IDEA中,请执行以下步骤:1)转到模块设置,然后转到工件,添加JAR并定义主类。2)然后转到菜单中的build,单击"build artifact",就得到了jar。

    即使当我改变了源文件夹,使用Scala而不是Java时,它也起了作用。


    检查您的本地.m2目录以获取此工件的子目录。如果exxts-删除它,然后再次执行maven更新