首页 文章

无法执行jar文件:“没有主要清单属性”

提问于
浏览
678

我已经安装了一个应用程序,当我尝试运行它时(它是一个可执行的jar)没有任何反应 . 当我从命令行运行它时:

java -jar“app.jar”

我收到以下消息:

“app.jar”中没有主要清单属性

通常,如果我自己创建了程序,我会在清单文件中添加一个主类属性 . 但在这种情况下,由于文件来自应用程序,我不能这样做 . 我也尝试提取jar以查看是否可以找到主类,但是有许多类,并且它们中没有一个在其名称中包含“main”一词 . 必须有办法解决这个问题,因为程序在其他系统上运行良好 .

30 回答

  • 11

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

    apply plugin: 'java'
    
    jar {
        manifest {
            attributes 'Main-Class': 'com.package.app.Class'
        }
    }
    
  • 6

    对我来说,没有一个答案真正有用 - 我将清单文件放在正确的位置,包含Main-Class和所有内容 . 让我绊倒的是:

    警告:您要从中创建清单的文本文件必须以新行或回车符结束 . 如果不以新行或回车结束,则不会正确解析最后一行 .

    source) . 在清单末尾添加换行符修复了它 .

  • 9

    使用IntelliJ IDEA创建jar时遇到了这个问题 . 见this discussion .

    为我解决的是重新创建jar工件,选择JAR>来自具有依赖关系的模块,但不接受META-INF / MANIFEST.MF的默认目录 . 将它从 - / src / main / java更改为 - / src / main / resources .

    否则它在jar中包含一个清单文件,但不包括它应该具有的 - / src / main / java中的清单文件 .

  • 3

    如果jar没有关注the rules,那它就不是可执行的jar .

  • 2

    既然你已经添加了MANIFEST.MF,我想你应该考虑这个文件中Field的顺序 . 我的环境是 java version "1.8.0_91"

    和我的MANIFEST.MF一样

    // 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
    

    但是,如下所示

    Manifest-Version: 1.0
    Main-Class: HelloWorldSwing
    Created-By: 1.8.0_91 (Oracle Corporation)
    
    //this run swing normally
    
  • 83

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

  • 3

    或者,您可以使用maven-assembly-plugin,如下例所示:

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.package.MainClass</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    

    在此示例中,部分中指定的所有依赖项jar将自动包含在您的单个jar中 . 请注意,jar-with-dependencies应该按字面意思放置,而不是替换为要包含的jar文件名 .

  • 26

    尝试此命令以包含jar:

    java -cp yourJarName.jar your.package..your.MainClass
    
  • 212

    我今天遇到了同样的问题 . 我的问题解决了我将META-INF移动到资源文件夹 .

  • 3

    (第一篇文章 - 所以它可能不干净)

    这是我对OS X 11.6,基于Maven的Netbeans 8.2程序的修复 . 到目前为止,我的应用程序是100%Netbeans - 没有调整(只有几个shell逃脱不可能!) .

    在这里和其他地方尝试了大部分答案都没有用,我回到了“用什么有用”的艺术 .

    这里的最佳答案(olivier-refalo thanx)看起来是正确的起点,但没有帮助 .

    看看其他有效的项目,我注意到清单行中有一些细微差别:

    没有

    • addClasspath,classpathPrefix(删除它们)

    • mainClass缺少"com."(使用NB - >项目属性 - >运行 - >主类 - >浏览指定)

    不知道为什么(我只有3个月进入java)或如何,但只能说这有效 .

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

    <manifest>
            <mainClass>mypackage.MyClass</mainClass>
        </manifest>
    
  • 2

    以上答案对我来说只是部分有用 . java -cp 是答案的一部分,但我需要更多关于如何识别要运行的类的具体信息 . 这对我有用:

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

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

    结果的顶线是:

    META-INF/
    META-INF/MANIFEST.MF
    somepath/
    somepath/App.class
    META-INF/maven/
    ...
    

    App.class包含要运行的主类 . 我不是百分百肯定你能不能总是假设你需要的课程是第一个,但它适合我 . 如果不是,我认为使用grep排除与库相关的结果以将类列表削减到可管理的大小并不太难 .

    从那里很简单:我只使用那条路径(减去“.class”后缀):

    java -cp /path/to/myjar.jar somepath/App
    
  • 660

    这是因为Java无法在MANIFEST.MF文件中找到Main属性 . Main属性是告诉java应该使用哪个类作为应用程序的入口点所必需的 . 在jar文件中,MANIFEST.MF文件位于META-INF文件夹中 . 想知道如何看待jar文件中的内容?使用WinRAR打开jar文件 .

    MANIFEST.MF中的主要属性如下所示:

    Main-Class: <packagename>.<classname>
    

    当MANIFEST.MF文件中缺少此行时,您会收到此“无主要清单属性”错误 .

    在MANIFEST.MF文件中指定此属性真是一团糟 .

    更新:我刚刚找到了一个非常简洁的方法来指定应用程序在eclipse中的入口点 . 当你说出口,

    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

  • 10

    我个人认为这里的所有答案都是误解了这个问题 . 答案就在于spring-boot如何构建.jar . 每个人都知道Spring Boot会设置一个这样的清单,它与每个人都不同 asssumption 这是一个标准的.jar启动,它可能是也可能不是:

    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 执行?

  • 5

    我遇到过同样的问题 . 通过向pom文件添加以下行使其工作 . 该插件将确保您的应用程序的构建过程包含所有必要的步骤 .

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

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

    清单 - 版本:1.0创建者:1.8.0_51(Oracle Corporation)

    并且不包含“Main-Class”声明,那么我认为你找到了你的问题 .

    不过,我不知道如何解决它 . 我在StackOverflow上检查了其他有相同/类似问题的人,但找不到答案 . 但是有了这些信息,您可能会获得更好的帮助(假设您遇到与我相同的问题) .

    *Edit: I had tried with a manifest-file but didn't get it to work, but my mistake was to only name one of the classes when creating the jar-file. I wrote .class instead and it works now.

    Although I don't know why there is a need to create a manifest-file. But I guess it's fine as long as it works.

  • 5

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

    其次,要使jar可执行...你需要jar一个名为META-INF / MANIFEST.MF的文件

    文件本身应该(至少)这一个班轮:

    Main-Class: com.mypackage.MyClass
    

    其中 com.mypackage.MyClass 是持有public static void main(String [] args)入口点的类 .

    请注意,有几种方法可以使用CLI,Maven,Ant或Gradle完成此操作:

    对于 CLI ,以下命令将执行:(tks @ dvvrtjar cmvf META-INF/MANIFEST.MF <new-jar-filename>.jar <files to include>

    对于 Maven ,类似以下代码段的内容应该可以解决问题 . 请注意,这只是插件定义,而不是完整的 pom.xml

    <build>
      <plugins>
        <plugin>
          <!-- Build an executable JAR -->
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.1.0</version>
          <configuration>
            <archive>
              <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>com.mypackage.MyClass</mainClass>
              </manifest>
            </archive>
          </configuration>
        </plugin>
      </plugins>
    </build>
    

    (选择适合您项目的<version> . )

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

    <jar destfile="build/main/checksites.jar">
      <fileset dir="build/main/classes"/>
      <zipfileset includes="**/*.class" src="lib/main/some.jar"/>
      <manifest>
        <attribute name="Main-Class" value="com.acme.checksites.Main"/>
      </manifest>
    </jar>
    

    致谢Michael Niemand -

    对于 Gradle

    plugins {
        id 'java'
    }
    
    jar {
        manifest {
            attributes(
                    'Main-Class': 'com.mypackage.MyClass'
            )
        }
    }
    
  • 0

    我有同样的问题 . 这里提到的很多解决方案并没有试图给你一个总结的方法到 pack jar files from the command line .

    • 如果要在包中包含 .class 文件,请在 .java 的开头添加包 .

    Test.java

    package testpackage;
    
    public class Test
    {
        ...
    }
    
    • 使用 .class 文件编译代码,最后使用包名称给出的结构:
    javac -d . Test.java
    

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

    • 打包 .jar 文件时,需要指示jar例程如何打包它 . 这里我们使用选项set cvfeP . 这是 keep the package structure (选项 P ), specify the entry point ,以便清单文件包含有意义的信息(选项 e ) . 选项 f 允许您指定文件名,选项 c 创建存档,选项 v 将输出设置为详细 . 这里需要注意的重要事项是 Pe .

    然后是我们想要的 jar 的名字 test.jar .

    然后是切入点 .

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

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

    test.jar

    META-INF
    | MANIFEST.MF
    testpackage
    | Test.class
    

    MANIFEST.MF应包含以下内容

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

    如果您手动编辑清单 be sure to keep the newline at the end ,否则java无法识别它 .

    • .jar 文件执行
    java -jar test.jar
    
  • 18

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

    -jar 选项仅在JAR文件是可执行JAR文件时有效,这意味着它必须具有包含 Main-Class 属性的清单文件 . 请参阅Packaging Programs in JAR Files以了解如何创建可执行JAR .

    如果它不是可执行的JAR,那么你需要运行程序,例如:

    java -cp app.jar com.somepackage.SomeClass
    

    其中 com.somepackage.SomeClass 是包含运行程序的 main 方法的类 . (这个类是什么取决于程序,它提供了's impossible to tell from the information you') .

  • 3

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

    例如:在jar创建中缺少选项m

    以下作品:

    jar -cvfm MyJar.jar Manifest.txt *.class
    
  • 0

    我有一个类似的问题,在下面的语法中成功创建.war文件: -

    jar [jar-file] [manifest-file]

    manifest在创建(c)或更新(u)JAR文件时,清单操作数定义预先存在的清单文件,其中包含要包含在JAR文件中的MANIFEST.MF中的属性的名称和值 . 如果f选项存在'[1]',则必须指定清单操作数 .

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

    **jar -cvf foo.war ***

    说实话,我不知道这是不是最好的做法,但它为我做的工作:) .

  • 21

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

    Netbeans project properties

    • 转到项目的 properties .

    • 点击 Run .

    • 使用 browse 指定项目的主类 .

    • buildrun Jar文件 .

  • 0

    我遇到了同样的问题,现在已经解决了:)只需按照以下步骤操作,错误可能适用于任何事情,但以下步骤可使流程更加顺畅 . 我花了很多时间来找到解决方案 .

    1.尝试重新启动Eclipse(如果您使用Eclipse构建JAR文件) - >实际上这有助于我导出JAR文件的问题正常 .

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

    • 此后,将Java Dynamic项目导出为“Runnable JAR”文件,而不是JAR文件 .

    • 在Java启动配置中,选择您的主类 .

    • 导出jar文件后,使用以下命令执行 . java -cp [Your JAR] .jar [完整包] .MainClass例如:java -cp AppleTCRuleAudit.jar com.apple.tcruleaudit.classes.TCRuleAudit

    • 您可能面临不受支持的java版本错误 . 修复是更改shell bash配置文件中的java_home以匹配用于在eclipse中编译项目的java版本 .

    希望这可以帮助!如果您还有任何问题,请告诉我 .

  • 0

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

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>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>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
  • 3

    I found a new solution to bad manifest generation !

    • 使用像WinRAR这样的zip编辑器打开jar文件

    • 点击META-INF

    • 添加或编辑

    • 添加:

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

    • 清单 - 版本:1.0

    • Main-Class:package.ex.com.views.mainClassName

    • 保存文件并将其添加到zip

    • 编辑:

    • 拖出文件修改MANIFEST.MF以添加上一行

    • 打开cmd并输入:java -jar c:/path/JarName.jar

    它现在应该工作正常!

  • 9

    任何可执行jar文件应该通过使用命令提示符(如java -jar app.jar)单击或运行来运行(使用“如果jar的路径包含空格” - 即java -jar“C:\ folder name \ app.jar”) . 如果您的可执行jar没有运行,这意味着它没有正确创建 .

    为了更好地理解,提取jar文件(或使用任何工具查看,对于Windows 7-Zip很好)并检查/META-INF/MANIFEST.MF下的文件 . 如果您发现任何条目,如

    Main-Class:your.package.name.ClaaswithMain - 那就没关系,否则你必须提供它 .

    请注意在MANIFEST.MF文件中附加Main-Class条目,检查保存位置!

  • 2

    对于maven,这就解决了它(对我来说,对于GitHub上的Veetle代码库):

    <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>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>
    

    干杯...

  • 2

    我刚才得到同样的错误 . 如果你正在使用 gradle ,只需在你的 gradle.build 中添加下一个:

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

    其中 com.company.project.MainClass 路径为ur类的 public static void main(String[] args) 方法 .

  • 1

    如果您使用命令行来汇编.jar,则可以指向main而不添加Manifest文件 . 例:

    jar cfve app.jar TheNameOfClassWithMainMethod *.class
    

    (param“e”这样做:TheNameOfClassWithMainMethod是类的名称,其方法为main()和app.jar - 可执行文件的名称.jar和* .class - 只是要汇编的所有类文件)

  • 2

    您可以只需按照此步骤创建一个jar文件

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

    运行jar文件时,运行就像这样

    java -cp jarfile-name main-classname
    
  • 15

    检查MANIFEST.MF内的jar文件Main-Class是否可用

    first.java

    class first
    {
            public static void main (String arg[ ])
            {
               System.out.println("Welcome to the world of Java");
            }
    }
    

    Before

    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
    

    After:

    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
    

相关问题