JAR-Datei kann nicht ausgeführt werden: „kein Hauptmanifestattribut“

971

Ich habe eine Anwendung installiert. Wenn ich versuche, sie auszuführen (es ist eine ausführbare JAR-Datei), passiert nichts. Wenn ich es von der Kommandozeile aus starte mit:

java -jar "app.jar"

Ich erhalte die folgende Nachricht:

kein Hauptmanifestattribut in "app.jar"

Wenn ich das Programm selbst erstellt hätte, hätte ich der Manifestdatei normalerweise ein Hauptklassenattribut hinzugefügt. Aber in diesem Fall kann ich das nicht tun, da die Datei aus einer Anwendung stammt. Ich habe auch versucht, das Glas zu extrahieren, um zu sehen, ob ich die Hauptklasse finden konnte, aber es gibt zu viele Klassen, und keine von ihnen hat das Wort "main" im Namen. Es muss eine Möglichkeit geben, dies zu beheben, da das Programm auf anderen Systemen einwandfrei ausgeführt wird.

Ewoud
quelle
Suchen Sie nach Hauptmethoden; Sie können sich nicht auf Klassennamen verlassen.
Dave Newton
2
Ich weiß, aber da ich nur .class-Dateien habe, kann ich die Methoden nicht wirklich sehen. Oder kann ich?
Ewoud
Sie tippen die Anführungszeichen nicht wirklich ein, oder? In jedem Fall gibt es eine Reihe von Möglichkeiten, Methoden anzuzeigen, einschließlich der Verwendung javap. Vielleicht möchten Sie es entpacken und nachsehen, ob es tatsächlich kein Manifest gibt.
Dave Newton
Verwandte: mit Abhängigkeiten: stackoverflow.com/a/23986765/360211
Weston
Was ist, wenn ich keine Hauptklasse habe, da ich den Code mit CommandLineJobRunner
Kamini am

Antworten:

946

Erstens ist es irgendwie komisch, dich rennen zu sehen java -jar "app"und nichtjava -jar app.jar

Zweitens müssen Sie eine Datei mit dem Namen META-INF / MANIFEST.MF erstellen, um eine JAR-Datei ausführbar zu machen

Die Datei selbst sollte (mindestens) diesen einen Liner haben:

Main-Class: com.mypackage.MyClass

Wo com.mypackage.MyClassbefindet sich die Klasse, die den öffentlichen statischen void main- Einstiegspunkt (String [] args) enthält?

Beachten Sie, dass es verschiedene Möglichkeiten gibt, dies entweder mit der CLI, Maven, Ant oder Gradle zu erreichen:

Für die CLI reicht der folgende Befehl aus: (tks @ dvvrt ) jar cmvf META-INF/MANIFEST.MF <new-jar-filename>.jar <files to include>

Für Maven sollte so etwas wie das folgende Snippet den Trick machen. Beachten Sie, dass dies nur die Plugin-Definition ist, nicht die vollständige 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>

(Wählen Sie eine <version>für Ihr Projekt geeignete.)

Für Ant sollte das folgende Snippet helfen:

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

Credits Michael Niemand -

Für Gradle :

plugins {
    id 'java'
}

jar {
    manifest {
        attributes(
                'Main-Class': 'com.mypackage.MyClass'
        )
    }
}
Olivier Refalo
quelle
15
In Ant ist sein <manifest> <attribute name = "Main-Class" value = "com.mypackage.MyClass" /> </ manifest> innerhalb des <jar> -Elements
Michael Niemand
1
Vielen Dank. Ich wollte nur hinzufügen, dass Sie Abhängigkeiten wie folgt in den lib-Ordner kopieren können: stackoverflow.com/a/996915/1121497 . Da der Klassenpfad diesen libOrdner enthält, müssen Sie nur das JAR mit ausführen, java -jar myproject.jarund es werden die Abhängigkeiten gefunden.
Ferran Maylinch
4
WIE MAN "eine Datei mit dem Namen META-INF / MANIFEST.MF jar"? Ich habe ein .jar einerseits und ein .MF andererseits. Wie verbinde ich sie miteinander? Ich habe das Manifest in den gleichen Ordner wie die .jar gelegt, aber es funktioniert nicht. Ich habe immer noch das Problem!
Wicelo
4
@Wicelo Um beim Erstellen einer JAR-Datei eine bestimmte MANIFEST.MF-Datei anzugeben, verwenden Sie das Flag m für JAR. z.B. jar cmvf META-INF/MANIFEST.MF <new-jar-filename>.jar <files to include>
dvvrt
1
Hinweis: Für Maven hatte ich bereits ein maven-jar-pluginElement in der VSC-generierten Maven-Datei, daher habe ich den <configuration>Abschnitt hinzugefügt .
Aaron Franke
279

Das hätte java -jar app.jarstatt sein sollen java -jar "app".

Die -jarOption funktioniert nur, wenn die JAR-Datei eine ausführbare JAR-Datei ist. Dies bedeutet, dass sie eine Manifestdatei mit einem Main-ClassAttribut enthalten muss. Informationen zum Erstellen einer ausführbaren JAR finden Sie unter Packen von Programmen in JAR-Dateien .

Wenn es sich nicht um eine ausführbare JAR handelt, müssen Sie das Programm folgendermaßen ausführen:

java -cp app.jar com.somepackage.SomeClass

Wo com.somepackage.SomeClassist die Klasse, die die mainMethode zum Ausführen des Programms enthält ? (Was diese Klasse ist, hängt vom Programm ab. Es ist unmöglich, anhand der von Ihnen angegebenen Informationen zu erkennen.)

Jesper
quelle
3
Vielen Dank für Ihre Antwort, aber Ihre Lösung funktioniert nur, wenn ich den Namen der Klasse kenne, die die Hauptmethode enthält. Und es war ein Tippfehler ... Es sollte "app.jar" sein. Aber wie erklären Sie, warum es auf anderen Systemen ausgeführt wird, indem Sie einfach auf die Datei doppelklicken?
Ewoud
Wenn es sich tatsächlich um eine ausführbare JAR handelt, können Sie die Manifestdatei extrahieren (sie befindet sich im META-INFVerzeichnis innerhalb der JAR-Datei). Es sollte ein Main-ClassAttribut enthalten , das Ihnen den Namen der Hauptklasse gibt.
Jesper
Wenn es nicht auf einem System ausgeführt wird, hat dieses System möglicherweise eine zu alte Java-Version. Wenn die JAR beispielsweise mit Java 7 kompiliert wurde, können Sie sie nicht auf einem System mit Java 6 oder älter ausführen.
Jesper
Das ist lustig, da auf dem anderen System Win7 ausgeführt wird und auf diesem PC mit den Problemen Win8 ausgeführt wird.
Ewoud
2
@Jesper Hallo, was ist, wenn Eclipse das Standardpaket verwendet? Setze ich nur den Klassennamen?
Ogen
127

Alternativ können Sie das Maven-Assembly-Plugin verwenden, wie im folgenden Beispiel gezeigt:

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

In diesem Beispiel werden alle im Abschnitt angegebenen Abhängigkeitsgläser automatisch in Ihr einzelnes Glas aufgenommen. Beachten Sie, dass jar-with-dependencies wörtlich so gesetzt werden sollte, dass sie nicht durch die jar-Dateinamen ersetzt werden, die Sie einschließen möchten.

CodeBrew
quelle
3
Perfekt, das funktioniert. Es bündelt alle Abhängigkeiten in einer JAR-Datei, sodass Sie ein Projekt kompilieren / erstellen und sofort ausführen können.
Paul
2
Im Kontext des Shadow-Plugins muss man der Hilfe bei Executable JAR folgen .
Koppor
3
Das hat maven-assembly-pluginfunktioniert. maven-jar-pluginnicht.
Martynas Jusevičius
Hinweis: Fügen Sie diesen Code in Ihre pom.xmlDatei ein <build><plugins> PUT IT HERE </plugins></build>und führen Sie dann das Maven-Paket aus (öffnen Sie in IDEA das Maven-Schiebemenü rechts und suchen Sie nach Projekt> Lebenszyklus> Paket). Dann befindet sich Ihre JAR-Datei im Zielordner. Prost!
Kirill Karmazin
Ich hatte wirklich Probleme mit diesem Problem ... Das funktioniert perfekt. Vielen Dank!
jmojico
60

Dies liegt daran, dass Java das Main-Attribut in der Datei MANIFEST.MF nicht finden kann. Das Main-Attribut ist erforderlich, um Java mitzuteilen, welche Klasse als Einstiegspunkt für die Anwendung verwendet werden soll. In der JAR-Datei befindet sich die Datei MANIFEST.MF im Ordner META-INF. Sie fragen sich, wie Sie sehen können, was sich in einer JAR-Datei befindet? Öffnen Sie die JAR-Datei mit WinRAR.

Das Hauptattribut in MANIFEST.MF sieht folgendermaßen aus:

Main-Class: <packagename>.<classname>

Sie erhalten den Fehler "Kein Hauptmanifestattribut", wenn diese Zeile in der Datei MANIFEST.MF fehlt.

Es ist wirklich ein großes Durcheinander, dieses Attribut in der Datei MANIFEST.MF anzugeben.

Update: Ich habe gerade eine wirklich gute Möglichkeit gefunden, den Einstiegspunkt der Anwendung in Eclipse anzugeben. Wenn Sie Exportieren sagen,

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.

Geben Sie hier die Bildbeschreibung ein

Sasanka Panguluri
quelle
32

Ich hatte das gleiche Problem. Durch Hinzufügen der folgenden Zeilen zur POM-Datei funktionierte es. Das Plugin stellt den Erstellungsprozess Ihrer Anwendung mit allen erforderlichen Schritten sicher.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
Naga Srinu Kapusetti
quelle
2
hat perfekt funktioniert, aber erwägen Sie, die Version ab April 2018 hinzuzufügen. <plugin> <groupId> org.springframework.boot </ groupId> <artifactId> spring-boot-maven-plugin </ifactId> <version> 2.0.1.RELEASE < / version> </ plugin>
Tenflex
Sorry, aber es ist keine Lösung, weil er nicht über Spring Boot spricht, es ist ein allgemeines Problem mit der Ausführung von JAR :)
LAMRIN TAWSRAS
Vielen Dank, dies hat das Problem für Spring Boot gelöst!
AleksandarT
Ich arbeite an Spring Boot 2.2.0.Release. Leider hat diese Lösung bei mir nicht funktioniert. Es funktioniert jedoch, wenn Sie von einer <parent>...</parent>Anwendung in der Datei pom.xml verwiesen haben . Ich vermute, wenn wir die parentpom.xml der Anwendung besuchen , bekommen wir eine klare Vorstellung.
Tusar
Ich habe endlich mein Problem mit dem Brauch gelöst repackage-classifier. Bitte besuchen Sie docs.spring.io/spring-boot/docs/2.2.0.RELEASE/maven-plugin/…
tusar
30

Die Gradle-Antwort besteht darin, eine JAR / Manifest / Attribute-Einstellung wie folgt hinzuzufügen:

apply plugin: 'java'

jar {
    manifest {
        attributes 'Main-Class': 'com.package.app.Class'
    }
}
QED
quelle
1
die bisher einfachste Antwort.
lasec0203
29

Ich hatte dieses Problem beim Erstellen eines Glases mit IntelliJ IDEA. Siehe diese Diskussion .

Was es für mich gelöst hat, war, das JAR-Artefakt neu zu erstellen und JAR> Von Modulen mit Abhängigkeiten zu wählen, aber das Standardverzeichnis für META-INF / MANIFEST.MF nicht zu akzeptieren. Ändern Sie es von - / src / main / java in - / src / main / resources.

Andernfalls wurde eine Manifestdatei in das JAR aufgenommen, aber nicht die in - / src / main / java, die es haben sollte.

Morgen Stern
quelle
Dies funktionierte bei mir mit IDEA 14.1.6. Ich habe auch die Build-Eigenschaft für pom.xml hinzugefügt, aber sie hatte keine Auswirkung. Aber Ihre Antwort hat es gelöst, danke.
Ab dem
3
Vielen Dank, dass Sie meinen Desktop vor der puren Frustration bewahrt haben, dass nichts anderes funktioniert;) Ihr Link scheint defekt zu sein, aber ich kann bestätigen, dass dies perfekt funktioniert. Getestet mit IntelliJ IDEA 2018.2.5 (Community Edition)
Matthias Bö
bestätigte, dass dies funktioniert, obwohl ich kein / resources-Verzeichnis habe
lxknvlk
28

Für Maven ist dies das, was es gelöst hat (für mich für eine Veetle-Codebasis auf GitHub):

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

Prost...

Dave
quelle
Ich fand, dass dies funktionierte, aber ich musste es ausführen, da mvn package shade:shadenur das Laufen mvn packagedas Shadow-Plugin nicht zum Laufen brachte.
Raystorm
24

Versuchen Sie diesen Befehl, um das Glas einzuschließen:

java -cp yourJarName.jar your.package..your.MainClass
Burhan ARAS
quelle
1
Eine Möglichkeit besteht darin, die Hauptklasse in pom.xml aufzunehmen und den Befehl java -jar zu verwenden, eine andere darin, den Befehl java -cp zu verwenden.
Gaurav Khare
15

Für mich hat keine der Antworten wirklich geholfen - ich hatte die Manifestdatei an der richtigen Stelle, die die Hauptklasse und alles enthielt. Was mich stolperte, war Folgendes:

Warnung: Die Textdatei, aus der Sie das Manifest erstellen, muss mit einer neuen Zeile oder einem neuen Zeilenumbruch enden. Die letzte Zeile wird nicht ordnungsgemäß analysiert, wenn sie nicht mit einer neuen Zeile oder einem neuen Wagenrücklauf endet.

( Quelle ). Durch Hinzufügen einer neuen Zeile am Ende des Manifests wurde dies behoben.

eis
quelle
11

Wenn Sie Maven verwenden, geben Sie Folgendes in den Pom ein

<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>
Shuang
quelle
3
Wer hat gesagt, dass dies ein Spring Boot-Projekt ist?
James.garriss
2
@ james.garriss Nun, ich würde sagen, ich bin zu diesem Beitrag gekommen, um nach no main manifest attributeFehlern zu suchen , aber ich arbeite an einer Spring-Boot-Anwendung, daher hat mir diese Antwort geholfen. Ich wusste bereits, wie man eine META-INF/MANIFEST.MFDatei erstellt, aber nicht, wie Spring-Boot automatisch damit umgeht.
Vishrant
5
Ich sehe keinen Grund, diese Antwort abzulehnen. Wenn Sie nicht verwenden, spring-bootignorieren Sie es einfach. Stackoverflow hilft auch dabei, ein eigenes Issue-Repository zu erstellen, mit dem Sie beim Programmieren konfrontiert sind.
Vishrant
@Vishrant Ich weiß nichts über andere, aber ich habe abgelehnt, weil diese Antwort die gestellte Frage nicht anspricht. Es mag gerade passiert sein , Ihre Frage zu beantworten, aber Ihre Frage war nicht wirklich das, was gestellt wurde.
Bane
@Bane sicher. Aber die Frage kann im weitesten Sinne genommen werden, und diese Antwort trifft darauf zu und kann anderen in dem Sinne helfen, wann sie Spring Boot verwenden werden.
Vishrant
10

Ich hatte heute das gleiche Problem. Mein Problem wurde gelöst, als META-INF in den Ressourcenordner verschoben wurde.

MTA
quelle
Das hat auch bei mir funktioniert. Versuchen Sie es, wenn Sie Jetbrains IntelliJ
NickSoft
Vielen Dank,
Das hat auch bei Intellij für mich funktioniert. Danke mann.
Waqas
10

Ich habe gerade den gleichen Fehler bekommen. Wenn Sie verwenden gradle, fügen Sie einfach das nächste in ur hinzu gradle.build:

apply plugin: 'java'

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

Wo com.company.project.MainClassPfad zu Ihrer Klasse mit public static void main(String[] args)Methode.

Binakot
quelle
Das hat mir geholfen! Gradle-Tutorials hatten unter Verwendung des mainClassNameVariablensatzes der obersten Ebene angegeben , aber das hilft nur beim gradle runBefehl, nicht beim Erstellen einer ausführbaren .jar
kevlarr
8

Das MAVEN-Problem besteht darin, dass versucht wird, die erste MANIFEST.MF-Datei aus der ersten Bibliothek aus Abhängigkeiten anstelle von UNSEREM EIGENEN MANIFEST.MF einzuschließen, wenn Sie Artefakte verwenden! .

  1. Benennen Sie yourjar.jar in yourjar.zip um
  2. Öffnen Sie die Datei MANIFEST.MF unter META-INF \ MANIFEST.MF
  3. Kopieren Sie die echte MANIFEST.MF, die MAVEN bereits in Ihrem Projekt generiert hat. Dazu gehören:

    Manifest-Version: 1.0 Hauptklasse: yourpacket.yourmainclass (zum Beispiel info.data.MainClass)

  4. Ersetzen Sie den Inhalt von MANIFEST.MF aus youjar.zip damit.

  5. Benennen Sie yourjar.zip in yourjar.jar zurück.
  6. Jetzt funktioniert java -jar yourjar.jar perfekt.

ODER!

Erstellen Sie einfach Ihre eigene MANIFEST.MF und:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <archive>
            <manifestFile> Your path like: src/main/resources/META-INF/MANIFEST.MF </manifestFile>
            <index>true</index>
                <manifest>
                    <addClasspath>true</addClasspath>
                </manifest>
        </archive>
    </configuration>
</plugin>

Wenn Sie jedoch das Maven-Bedienfeld (oder die Maven-Befehlszeile) verwenden, können Sie es zwingen, ein eigenes Manifest zu generieren und es in die JAR-Datei aufzunehmen.

  1. Fügen Sie dem Build-Abschnitt von you pom.xml diesen Code hinzu:

    <plugins>
        <plugin>
    
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.2.0</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
    
            <archive>
    
                <index>true</index>
    
                <manifest>
                    <addClasspath>true</addClasspath>
                    <mainClass> yourpacket.yourmainclass (for exmaple info.data.MainClass)</mainClass>
                </manifest>
                <manifestEntries>
                    <mode>development</mode>
                    <url>${project.url}</url>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>

  2. Öffnen Sie das MAVEN-Bedienfeld (in Intellij) und führen Sie "Installieren" aus. Es generiert die MANIFEST-Datei und kompiliert die JAR-Datei mit allen Abhängigkeiten in den Ordner "Target". Außerdem wird es im lokalen Maven-Repository installiert.

Yury Finchenko
quelle
5

Ich hatte das gleiche Problem und es ist jetzt behoben :) Befolgen Sie einfach die folgenden Schritte und der Fehler kann für alles sein, aber die folgenden Schritte machen den Prozess reibungsloser. Ich verbringe viel Zeit damit, die Lösung zu finden.

1. Versuchen Sie, die Eclipse neu zu starten (wenn Sie Eclipse zum Erstellen einer JAR-Datei verwenden) -> Dies hat meinem Problem beim ordnungsgemäßen Exportieren der JAR-Datei geholfen.

2.Versuchen Sie nach dem Neustart von Eclipse, ob Ihre Eclipse die Hauptklasse / -methode von Ihrem Java-Projekt erkennen kann -> Rechtsklick -> Ausführen als -> Konfigurationen ausführen -> Haupt -> Klicken Sie auf die Schaltfläche Suchen um zu sehen, ob Ihre Eclipse in der JAR-Datei nach Ihrer Hauptklasse suchen kann. -> Dies dient zur Überprüfung, ob die JAR-Datei den Einstiegspunkt in die Hauptklasse hat.

  1. Exportieren Sie anschließend Ihr Java Dynamic-Projekt als "Runnable JAR" -Datei und nicht als JAR-Datei.

  2. Wählen Sie in der Java-Startkonfiguration Ihre Hauptklasse aus.

  3. Verwenden Sie nach dem Exportieren der JAR-Datei den folgenden Befehl, um sie auszuführen. java -cp [Ihre JAR] .jar [Komplettpaket] .MainClass zB: java -cp AppleTCRuleAudit.jar com.apple.tcruleaudit.classes.TCRuleAudit

  4. Möglicherweise tritt der nicht unterstützte Java-Versionsfehler auf. Das Update besteht darin, das java_home in Ihrem Shell-Bash-Profil so zu ändern, dass es mit der Java-Version übereinstimmt, die zum Kompilieren des Projekts in Eclipse verwendet wird.

Hoffe das hilft! Bitte lassen Sie mich wissen, wenn Sie noch Probleme haben.

KarthikPon
quelle
5

Ich hatte das gleiche Problem. Viele der hier genannten Lösungen haben mir nicht das ganze Bild vermittelt, daher werde ich versuchen, Ihnen eine Zusammenfassung des Packens von JAR-Dateien über die Befehlszeile zu geben .

  1. Wenn Sie Ihre .classDateien in Paketen haben möchten , fügen Sie das Paket am Anfang des hinzu .java.

    Test.java

    package testpackage;
    
    public class Test
    {
        ...
    }
  2. Um Ihren Code mit Ihren .classDateien zu kompilieren, die die durch den Paketnamen angegebene Struktur haben, verwenden Sie:

    javac -d . Test.java

    Das -d .macht der Compiler die Verzeichnisstruktur erstellen Sie wollen.

  3. Wenn Sie die .jarDatei verpacken , müssen Sie die JAR-Routine anweisen, wie sie verpackt wird . Hier verwenden wir den Optionssatz cvfeP. Dies dient dazu , die Paketstruktur beizubehalten (Option P) und den Einstiegspunkt anzugeben, damit die Manifestdatei aussagekräftige Informationen enthält (Option e). Mit Option fkönnen Sie den Dateinamen angeben, Option cerstellt ein Archiv und Option vsetzt die Ausgabe auf ausführlich. Die wichtigsten Dinge, die hier zu beachten sind, sind Pund e.

    Dann kommt der Name des Glases, das wir wollen test.jar.

    Dann kommt der Einstiegspunkt.

    Anschließend werden -C . <packagename>/die Klassendateien aus diesem Ordner abgerufen, wobei die Ordnerstruktur beibehalten wird.

    jar cvfeP test.jar testpackage.Test -C . testpackage/
  4. Überprüfen Sie Ihre .jarDatei in einem Zip-Programm. Es sollte die folgende Struktur haben

    test.jar

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

    Die MANIFEST.MF sollte Folgendes enthalten

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

    Wenn Sie Ihr Manifest von Hand bearbeiten, müssen Sie den Zeilenumbruch am Ende behalten, da Java ihn sonst nicht erkennt.

  5. Führen Sie Ihre .jarDatei mit aus

    java -jar test.jar
CodeMonkey
quelle
1
Der 4. Schritt Ihrer Antwort ist sehr wichtig! Mein Manifest funktionierte nicht wegen dieser neuen Zeile am Ende, von der ich nicht wusste, dass ich sie setzen musste. Alle Antworten, die ich zu diesem Thema besucht habe (oft), haben dies nicht erwähnt, und es ist obligatorisch für alle, die Maven, Ant, Gradle usw. nicht verwenden.
Maude
1
@ Maude danke für das Feedback. Genau deshalb habe ich die Antwort mit dem fett gedruckten Zeilenumbruch hinzugefügt . Ich habe tagelang gesucht, bis ich dies durch einen Vergleich mit einem automatisch generierten Manifest herausgefunden habe.
CodeMonkey
Hah, danke. Ich habe gerade meinen Kopf gegen diese Newline-Sache geschlagen.
Richard Thomas
5

Ich persönlich denke, dass alle Antworten hier die Frage falsch verstehen. Die Antwort darauf liegt in dem Unterschied, wie Spring-Boot die .jar baut. Jeder weiß, dass Spring Boot ein solches Manifest erstellt, das von jeder Annahme abweicht, dass es sich um einen Standard-JAR-Start handelt, bei dem es sich möglicherweise um Folgendes handelt oder nicht:

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

Vielleicht muss es mit org.springframework.boot.loader.JarLauncherauf dem Klassenpfad ausgeführt werden?

Djangofan
quelle
Das klingt vielversprechend. Wie genau fügen Sie JarLauncher zum Klassenpfad hinzu?
MarkHu
4

Jede ausführbare JAR-Datei sollte entweder durch Klicken oder Ausführen über eine Eingabeaufforderung wie java -jar app.jar ausgeführt werden (verwenden Sie "wenn der Pfad des JAR Leerzeichen enthält" - dh Java -jar "C: \ Ordnername \ app.jar"). Wenn Ihr ausführbares JAR nicht ausgeführt wird, bedeutet dies, dass es nicht ordnungsgemäß erstellt wurde.

Extrahieren Sie zum besseren Verständnis die JAR-Datei (oder zeigen Sie sie mit einem beliebigen Tool an, für Windows 7-Zip ist sie hilfreich) und überprüfen Sie die Datei unter /META-INF/MANIFEST.MF. Wenn Sie einen Eintrag wie finden

Hauptklasse: your.package.name.ClaaswithMain - dann ist es in Ordnung, sonst müssen Sie es bereitstellen.

Achten Sie darauf, dass Sie den Eintrag der Hauptklasse an die Datei MANIFEST.MF anhängen. Überprüfen Sie, wo Sie ihn speichern!

Shekh Akther
quelle
4

Sie können diesen Schritt einfach ausführen. Erstellen Sie eine JAR-Datei mit

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

Während Sie die JAR-Datei ausführen, führen Sie sie einfach so aus

 java -cp jarfile-name main-classname
Koneri
quelle
4

Möglicherweise haben Sie die JAR-Datei nicht ordnungsgemäß erstellt:

Beispiel: Fehlende Option m bei der JAR-Erstellung

Folgendes funktioniert:

jar -cvfm MyJar.jar Manifest.txt *.class
satheesh.v
quelle
4

Wenn Sie die Befehlszeile zum Zusammenstellen von .jar verwenden, können Sie auf die Hauptzeile zeigen, ohne die Manifest-Datei hinzuzufügen. Beispiel:

jar cfve app.jar TheNameOfClassWithMainMethod *.class

(param "e" macht das: TheNameOfClassWithMainMethod ist ein Name der Klasse mit der Methode main () und app.jar - Name der ausführbaren Datei .jar und * .class - nur alle zu montierenden Klassendateien)

Andrey
quelle
3

Bei mir trat dieser Fehler einfach auf, weil ich vergessen hatte, Eclipse mitzuteilen, dass ich eine ausführbare JAR-Datei und keine einfache Bibliotheks-JAR-Datei haben wollte. Wenn Sie also die JAR-Datei in Eclipse erstellen, stellen Sie sicher, dass Sie auf das rechte Optionsfeld klicken

Neeraj Bhatnagar
quelle
3

Die obigen Antworten waren für mich nur teilweise hilfreich. java -cpwar Teil der Antwort, aber ich brauchte genauere Informationen darüber, wie ich die auszuführende Klasse identifizieren kann. Folgendes hat bei mir funktioniert:

Schritt 1: Finden Sie die Klasse, die ich ausführen muss

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

Die obersten Zeilen des Ergebnisses waren:

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

App.class enthielt die auszuführende Hauptklasse. Ich bin mir nicht 100% sicher, ob Sie immer davon ausgehen können, dass die Klasse, die Sie brauchen, die erste ist, aber es war für mich. Wenn dies nicht der Fall ist, würde ich mir vorstellen, dass es nicht allzu schwierig ist, grep zu verwenden, um bibliotheksbezogene Ergebnisse auszuschließen und die Klassenliste auf eine überschaubare Größe zu reduzieren.

Von da an war es einfach: Ich benutze nur diesen Pfad (abzüglich des Suffixes ".class"):

java -cp /path/to/myjar.jar somepath/App
mwag
quelle
Es ist nicht immer die erste Klasse. Fast nie. Befehlszeile sollte sein java -cp ... somepackage.App.
Marquis von Lorne
2

Da Sie MANIFEST.MF hinzugefügt haben, sollten Sie die Reihenfolge der Felder in dieser Datei berücksichtigen. Mein env ist java version "1.8.0_91"

und mein MANIFEST.MF wie hier

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

Dies läuft jedoch wie unten durch

Manifest-Version: 1.0
Main-Class: HelloWorldSwing
Created-By: 1.8.0_91 (Oracle Corporation)

//this run swing normally
Fan Yer
quelle
Eh? Die Reihenfolge ist unerheblich. Unklar, was Sie behaupten.
Marquis von Lorne
2

(erster Beitrag - daher ist es möglicherweise nicht sauber)

Dies ist mein Fix für OS X 11.6, Maven-basiertes Netbeans 8.2-Programm. Bis jetzt besteht meine App zu 100% aus Netbeans - keine Optimierung (nur ein paar Shell-Escapes für das Unmögliche!).

Nachdem ich die meisten Antworten hier und anderswo vergeblich ausprobiert hatte, kehrte ich zur Kunst zurück, "zu verwenden, was funktioniert".

Die beste Antwort hier ( Olivier-Refalo- Danke) schien der richtige Startpunkt zu sein, half aber nicht.

Bei anderen Projekten, die funktionierten, stellte ich einige geringfügige Unterschiede in den Manifestlinien fest:

  1. addClasspath, classpathPrefix fehlten (löschten sie)
  2. mainClass fehlte die "com". (Verwenden Sie NB -> Projekteigenschaften-> Ausführen-> Hauptklasse-> Durchsuchen, um anzugeben)

Ich bin mir nicht sicher warum (ich bin erst 3 Monate in Java) oder wie, kann aber nur sagen, dass dies funktioniert hat.

Hier wird nur der modifizierte Manifestblock verwendet:

    <manifest>
        <mainClass>mypackage.MyClass</mainClass>
    </manifest>
MichaelT
quelle
2

Ich habe eine neue Lösung für die Erzeugung schlechter Manifeste gefunden!

  1. Öffnen Sie die JAR-Datei mit einem Zip-Editor wie WinRAR
  2. Klicken Sie auf für META-INF

  3. Hinzufügen oder bearbeiten

    • Hinzufügen:

      • Erstellen Sie eine Textdatei mit dem Namen MANIFEST.MF in einem Ordner mit dem Namen META-INF und fügen Sie die folgende Zeile hinzu:

        • Manifest-Version: 1.0
        • Hauptklasse: package.ex.com.views.mainClassName
      • Speichern Sie die Datei und fügen Sie sie der Zip-Datei hinzu

    • Bearbeiten:

      • Ziehen Sie die Datei heraus und ändern Sie die Datei MANIFEST.MF, um die vorherige Zeile hinzuzufügen
  4. Öffnen Sie cmd und geben Sie Folgendes ein: java -jar c: /path/JarName.jar

Es sollte jetzt gut funktionieren!

Dave Beauchesne
quelle
2

Die meisten Lösungen haben bei mir nicht funktioniert, aber mein Lehrer hat mir geholfen. Ich möchte seine Lösung hier teilen. Ich habe das Kali Linux Terminal verwendet, sollte aber in allen Debians in Ordnung sein

javac *.java
nano MANIFEST.MF

im Dateityp

Hauptklasse: Hauptklasse oder wie auch immer Ihr Hauptdateiname lautet (stellen Sie sicher, dass Sie den Paketnamen hinzufügen, falls vorhanden).

jar -cvmf MANIFEST.MF new.jar *.class

Jetzt zum Ausführen der Datei verwenden

java -jar new.jar

oder Sie können zu den Eigenschaften der Datei gehen und überprüfen

Ausführung der Datei als Programm zulassen

Doppelklicken Sie darauf

Es hat mir geholfen, während die meisten der oben genannten Antworten dies nicht taten


quelle
1

Möglicherweise haben Sie das gleiche Problem wie ich. Schreiben Sie nach dem Erstellen Ihrer JAR-Datei jar xf app.jar META-INF/MANIFEST.MF. Dadurch wird eine Kopie der Datei in Ihr aktuelles Verzeichnis erstellt, damit Sie sie lesen können. Wenn es nur so etwas sagt wie:

Manifest-Version: 1.0

Erstellt von: 1.8.0_51 (Oracle Corporation)

und enthält nicht die "Main-Class" -Deklaration, dann haben Sie wohl Ihr Problem gefunden.

Ich weiß jedoch nicht, wie ich es lösen soll. Ich habe andere Personen mit gleichen / ähnlichen Problemen auf StackOverflow überprüft und konnte keine Antwort finden. Mit diesen Informationen können Sie jedoch möglicherweise eine bessere Hilfe erhalten (angesichts der Tatsache, dass Sie das gleiche Problem wie ich haben).

Bearbeiten: Ich hatte es mit einer Manifest-Datei versucht, aber es funktionierte nicht, aber mein Fehler war, beim Erstellen der JAR-Datei nur eine der Klassen zu benennen. Ich habe stattdessen * .class geschrieben und es funktioniert jetzt.

Obwohl ich nicht weiß, warum eine Manifestdatei erstellt werden muss. Aber ich denke, es ist in Ordnung, solange es funktioniert.

Gendarm
quelle
1

Ich hatte dieses Problem und habe es kürzlich in Netbeans 8 gelöst (siehe Abbildung unten):

Netbeans-Projekteigenschaften

  1. Gehen Sie zu den Eigenschaften Ihres Projekts.
  2. Klicken Sie auf Ausführen .
  3. Geben Sie die Hauptklasse Ihres Projekts mithilfe von Durchsuchen an .
  4. Erstellen Sie die Jar-Datei und führen Sie sie aus .
Abdelsalam Shahlol
quelle