Nie można wykonać pliku jar: „brak głównego atrybutu manifestu”

970

Zainstalowałem aplikację, kiedy próbuję ją uruchomić (jest to plik wykonywalny), nic się nie dzieje. Kiedy uruchamiam go z wiersza poleceń za pomocą:

java -jar „app.jar”

Otrzymuję następujący komunikat:

brak głównego atrybutu manifestu w „app.jar”

Normalnie, gdybym sam stworzył program, dodałbym główny atrybut klasy do pliku manifestu. Ale w tym przypadku, ponieważ plik pochodzi z aplikacji, nie mogę tego zrobić. Próbowałem też wyodrębnić słoik, aby sprawdzić, czy mogę znaleźć klasę główną, ale istnieje wiele klas i żadna z nich nie ma słowa „main” w nazwie. Musi istnieć sposób, aby to naprawić, ponieważ program działa poprawnie w innych systemach.

Ewoud
źródło
Poszukaj głównych metod; nie możesz polegać na nazwach klas.
Dave Newton
2
Wiem, ale ponieważ mam tylko pliki .class, tak naprawdę nie widzę metod. Czy mogę?
Ewoud
Naprawdę nie piszesz cytatów, prawda? W każdym razie istnieje wiele sposobów, aby zobaczyć metody, w tym użycie javap. Możesz jednak odpakować plik i sprawdzić, czy faktycznie nie ma manifestu.
Dave Newton,
Powiązane: z zależnościami: stackoverflow.com/a/23986765/360211
weston
co jeśli nie mam klasy głównej, ponieważ uruchamiam kod za pomocą CommandLineJobRunner
Kamini

Odpowiedzi:

946

Po pierwsze, to trochę dziwne, gdy widzisz, jak biegniesz, java -jar "app"a niejava -jar app.jar

Po drugie, aby jar mógł być wykonywalny ... musisz zgarnąć plik o nazwie META-INF / MANIFEST.MF

sam plik powinien mieć (przynajmniej) jedną linijkę:

Main-Class: com.mypackage.MyClass

Gdzie com.mypackage.MyClassjest klasa posiadająca publiczny punkt wejścia static void main (String [] args) .

Zauważ, że jest kilka sposobów, aby to zrobić za pomocą CLI, Maven, Ant lub Gradle:

W przypadku interfejsu wiersza polecenia wystarczy wykonać następujące polecenie: (tks @ dvvrt ) jar cmvf META-INF/MANIFEST.MF <new-jar-filename>.jar <files to include>

W przypadku Maven coś takiego jak poniższy fragment kodu powinno wystarczyć. Zauważ, że jest to tylko definicja wtyczki, a nie pełna 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>

(Wybierz <version>odpowiedni dla swojego projektu.)

W przypadku Anta poniższy fragment powinien pomóc:

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

Kredyty Michael Niemand -

Dla Gradle :

plugins {
    id 'java'
}

jar {
    manifest {
        attributes(
                'Main-Class': 'com.mypackage.MyClass'
        )
    }
}
Olivier Refalo
źródło
15
W Ant jego <manifest> <nazwa atrybutu = "Klasa główna" wartość = "com.mypackage.MyClass" /> </manifest> w elemencie <jar>
Michael Niemand
1
Dziękuję Ci. Chciałem tylko dodać, że możesz skopiować zależności do folderu lib przy pomocy: stackoverflow.com/a/996915/1121497 . Ponieważ ścieżka klasy zawiera ten libfolder, wystarczy wykonać jar za pomocą java -jar myproject.jari znajdzie zależności.
Ferran Maylinch
4
JAK „słoić plik o nazwie META-INF / MANIFEST.MF”? Mam z jednej strony plik .jar, a z drugiej strony plik .MF. Jak połączyć je ze sobą? Umieszczam manifest w tym samym folderze co .jar, ale to nie działa. Nadal mam problem!
Wicelo,
4
@Wicelo Aby określić konkretny plik MANIFEST.MF podczas tworzenia pliku jar, użyj flagi m dla jar. na przykład. jar cmvf META-INF/MANIFEST.MF <new-jar-filename>.jar <files to include>
dvvrt
1
Uwaga: W przypadku Maven miałem już maven-jar-pluginelement w pliku Maven wygenerowanym przez VSC, więc właśnie <configuration>do niego dodałem sekcję.
Aaron Franke,
279

To powinno być java -jar app.jarzamiast java -jar "app".

Ta -jaropcja działa tylko wtedy, gdy plik JAR jest wykonywalnym plikiem JAR, co oznacza, że ​​musi on zawierać plik manifestu z Main-Classatrybutem. Zobacz Pakowanie programów w plikach JAR, aby dowiedzieć się, jak utworzyć wykonywalny plik JAR.

Jeśli nie jest to wykonywalny plik JAR, musisz uruchomić program z czymś takim jak:

java -cp app.jar com.somepackage.SomeClass

gdzie com.somepackage.SomeClassjest klasa, która zawiera mainmetodę uruchamiania programu. (Czym jest ta klasa, zależy od programu, nie można stwierdzić na podstawie dostarczonych informacji).

Jesper
źródło
3
dzięki za odpowiedź, ale twoje rozwiązanie działa tylko wtedy, gdy znam nazwę klasy, która zawiera główną metodę. I to była literówka ... Miał być „app.jar”. Ale jak wyjaśnić, dlaczego działa on w innych systemach, klikając dwukrotnie plik?
Ewoud
Jeśli rzeczywiście jest to wykonywalny plik JAR, możesz wyodrębnić plik manifestu (znajduje się on w META-INFkatalogu w pliku JAR). Powinien zawierać Main-Classatrybut, który podaje nazwę głównej klasy.
Jesper
Jeśli nie działa w jednym systemie, oznacza to, że ten system może mieć zbyt starą wersję Java. Jeśli plik JAR jest na przykład skompilowany z Javą 7, nie można go uruchomić w systemie z Javą 6 lub starszą.
Jesper
To zabawne, ponieważ na innym systemie działa win7, a na tym komputerze z problemami działa win8.
Ewoud,
2
@Jesper Witam, a co jeśli Eclipse używa domyślnego pakietu? Czy po prostu podaję nazwę klasy?
Ogen
127

Alternatywnie możesz użyć wtyczki maven-assembly-plugin, jak pokazano w poniższym przykładzie:

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

W tym przykładzie wszystkie słoiki zależności określone w sekcji zostaną automatycznie dołączone do pojedynczego słoika. Zauważ, że jar-z-zależnościami należy dosłownie umieścić jako, a nie zastępować je nazwami plików jar, które chcesz dołączyć.

CodeBrew
źródło
3
Idealnie, to działa. Łączy wszystkie zależności w jeden słoik, dzięki czemu możesz skompilować / zbudować projekt i uruchomić go po wyjęciu z pudełka.
Paul
2
W kontekście wtyczki cieniowania należy postępować zgodnie z pomocą w pliku wykonywalnym JAR .
koppor
3
To maven-assembly-plugindziałało. maven-jar-pluginnie.
Martynas Jusevičius
Uwaga: umieść ten kod w swoim pom.xmlpliku, <build><plugins> PUT IT HERE </plugins></build>a następnie uruchom pakiet maven (w menu przesuwnym IDEA otwórz maven po prawej stronie, poszukaj projektu> Cykl życia> pakiet). Wtedy twój plik jar będzie w folderze docelowym. Twoje zdrowie!
Kirill Karmazin,
Naprawdę walczyłem z tym problemem ... Działa to doskonale. Dzięki!
jmojico
60

Wynika to z faktu, że Java nie może znaleźć atrybutu Main w pliku MANIFEST.MF. Atrybut Main jest niezbędny, aby powiedzieć java, której klasy powinien użyć jako punktu wejścia aplikacji. W pliku jar plik MANIFEST.MF znajduje się w folderze META-INF. Zastanawiasz się, jak możesz spojrzeć na zawartość słoika? Otwórz plik jar w WinRAR.

Główny atrybut w pliku MANIFEST.MF wygląda następująco:

Main-Class: <packagename>.<classname>

Ten błąd „brak głównego atrybutu manifestu” pojawia się, gdy brakuje tego wiersza w pliku MANIFEST.MF.

Określenie tego atrybutu w pliku MANIFEST.MF jest naprawdę ogromnym bałaganem.

Aktualizacja: Właśnie znalazłem naprawdę fajny sposób na określenie punktu wejścia aplikacji w środowisku Eclipse. Kiedy mówisz Eksportuj,

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.

wprowadź opis zdjęcia tutaj

Sasanka Panguluri
źródło
32

Miałem ten sam problem. dodając następujące wiersze do pliku pom, sprawiło, że działało. Wtyczka zapewni proces kompilacji aplikacji wraz ze wszystkimi niezbędnymi krokami.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
Naga Srinu Kapusetti
źródło
2
działało idealnie, ale rozważ dodanie wersji z kwietnia 2018 r. <plugin> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-maven-plugin </artifactId> <wersja> 2.0.1.RELEASE < / version> </plugin>
Tenflex
Przepraszam, ale to nie jest rozwiązanie, ponieważ nie mówi o wiosennym rozruchu, to ogólny problem z wykonaniem słoika :)
LAMRIN TAWSRAS
Wielkie dzięki, to rozwiązało problem wiosennego rozruchu!
AleksandarT
Pracuję na wiosennym rozruchu 2.2.0. Niestety to rozwiązanie nie działało dla mnie. Działa jednak, gdy <parent>...</parent>poleciłeś z aplikacji w pliku pom.xml. Domyślam się, że jeśli odwiedzimy parentplik pom.xml aplikacji, otrzymamy jasny pomysł.
tusar
W końcu rozwiązałem swój problem ze zwyczajem repackage-classifier. Proszę odwiedzić docs.spring.io/spring-boot/docs/2.2.0.RELEASE/maven-plugin/…
tusar
30

Odpowiedzią Gradle jest dodanie ustawienia jar / manifest / atrybuty w następujący sposób:

apply plugin: 'java'

jar {
    manifest {
        attributes 'Main-Class': 'com.package.app.Class'
    }
}
CO BYŁO DO OKAZANIA
źródło
1
najprostsza jak dotąd odpowiedź.
lasec0203
29

Miałem ten problem podczas tworzenia słoika za pomocą IntelliJ IDEA. Zobacz tę dyskusję .

Rozwiązaniem dla mnie było odtworzenie artefaktu jar, wybierając JAR> Z modułów z zależnościami, ale nie akceptując domyślnego katalogu dla META-INF / MANIFEST.MF. Zmień go z - / src / main / java na - / src / main / resources.

W przeciwnym razie zawierał plik manifestu w słoiku, ale nie ten, który powinien mieć w katalogu - / src / main / java.

poranna gwiazda
źródło
Działa to dla mnie z IDEA 14.1.6. Dodałem także właściwość build dla pom.xml, ale to nie miało żadnego efektu. Ale twoja odpowiedź rozwiązała to, dziękuję.
lsrom
3
Dzięki za uratowanie mojego pulpitu przed zranieniem czystą frustracją, że nic innego nie działa;) Twój link wydaje się zepsuty, ale mogę potwierdzić, że działa to idealnie. Testowane z IntelliJ IDEA 2018.2.5 (Community Edition)
Matthias Bö,
potwierdziło, że to działa, mimo że nie mam katalogu / resources
lxknvlk
28

W przypadku maven rozwiązało to (dla mnie, dla bazy kodowej Veetle na 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>

Twoje zdrowie...

Dave
źródło
Okazało się, że zadziałało, ale musiałem wykonać, ponieważ mvn package shade:shadesamo uruchomienie mvn packagenie spowodowało uruchomienia wtyczki cieniowania.
Raystorm,
24

Wypróbuj to polecenie, aby dołączyć jar:

java -cp yourJarName.jar your.package..your.MainClass
Burhan ARAS
źródło
1
Jednym ze sposobów jest włączenie głównej klasy do pom.xml i użycie komendy java -jar, innym sposobem jest użycie komendy java -cp.
Gaurav Khare
15

Dla mnie żadna z odpowiedzi tak naprawdę nie pomogła - miałem plik manifestu we właściwym miejscu, zawierający klasę główną i wszystko. To, co mnie potknęło, to:

Ostrzeżenie: plik tekstowy, z którego tworzysz manifest, musi kończyć się nową linią lub znakiem powrotu karetki. Ostatnia linia nie zostanie poprawnie przeanalizowana, jeśli nie zakończy się nową linią lub znakiem powrotu karetki.

( źródło ). Dodanie nowej linii na końcu manifestu naprawiło to.

eis
źródło
11

Jeśli korzystasz z Maven, dołącz do 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>
Shuang
źródło
3
Kto powiedział, że to był projekt Spring Boot?
james.garriss
2
@ james.garriss dobrze powiedziałbym, przyszedłem do tego postu szukając no main manifest attributebłędu, ale pracuję nad aplikacją rozruchu wiosennego, więc ta odpowiedź pomogła mi. Wiedziałem już, jak utworzyć META-INF/MANIFEST.MFplik, ale nie wiem, jak automatycznie uruchamia go Spring-boot.
Vishrant
5
Nie widzę powodu, by głosować za odrzuceniem tej odpowiedzi. Jeśli nie używasz, spring-bootzignoruj ​​to. Stackoverflow pomaga również w budowaniu własnego repozytorium problemów, z którym napotykasz podczas programowania.
Vishrant
@Vishrant Nie wiem o innych, ale głosowałem negatywnie, ponieważ ta odpowiedź nie odnosi się do postawionego pytania. Być może właśnie zdarzyło się, że odpowiedziałeś na twoje pytanie, ale twoje pytanie nie było tak naprawdę pytaniem.
Zmora
@Bane na pewno. ale pytanie można ująć w szerokim znaczeniu, a ta odpowiedź dotyczy go i może pomóc innym w tym sensie, kiedy użyją wiosennego rozruchu.
Vishrant
10

Miałem dzisiaj ten sam problem. Mój problem został rozwiązany, przenosząc META-INF do folderu zasobów.

MTA
źródło
To też działało dla mnie. Wypróbuj, jeśli używasz Jetbrains IntelliJ
NickSoft
Dziękuję, że naprawdę dla mnie zadziałało :)
Syed Mehtab Hassan
To działało również dla mnie w przypadku Intellij. Dziękuje.
Waqas
10

Właśnie dostałem ten sam błąd. Jeśli używasz gradle, po prostu dodaj następny w swoim gradle.build:

apply plugin: 'java'

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

Gdzie com.company.project.MainClassścieżka do twojej klasy z public static void main(String[] args)metodą.

Binakot
źródło
To mi pomogło! tutoriale gradle określiły za pomocą mainClassNamezestawu zmiennych najwyższego poziomu , ale to pomaga tylko w gradle runpoleceniach, a nie w tworzeniu pliku wykonywalnego .jar
kevlarr
8

Problem MAVEN polega na tym, że stara się dołączyć pierwszy plik MANIFEST.MF z pierwszej biblioteki z zależności zamiast NASZYCH WŁASNYCH MANIFEST.MF KIEDY UŻYWAĆ ARTYKUŁÓW! .

  1. Zmień nazwę twojar.jar na twojar.zip
  2. Otwórz plik MANIFEST.MF z META-INF \ MANIFEST.MF
  3. Skopiuj prawdziwy plik MANIFEST.MF, który już wygenerował w twoim projekcie przez MAVEN. Obejmuje to, że:

    Manifest-Version: 1.0 Main-Class: yourpacket.yourmainclass (na przykład info.data.MainClass)

  4. Zamień na nią zawartość pliku MANIFEST.MF z youjar.zip.

  5. Zmień nazwę pliku twojar.zip na yourjar.jar.
  6. Teraz java -jar twojar.jar działa idealnie.

LUB!

Po prostu stwórz własny plik MANIFEST.MF i:

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

Ale jeśli używasz panelu maven (lub wiersza poleceń maven), możesz zmusić go do wygenerowania własnego manifestu i włączenia go do pliku JAR.

  1. Dodaj do sekcji kompilacji pom.xml ten kod:

    <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. Otwórz panel MAVEN (w Intellij) i uruchom „Instaluj”. Wygeneruje plik MANIFEST i skompiluje właściwość plik JAR ze wszystkimi zależnościami w folderze „Target”. Zostanie również zainstalowany w lokalnym repozytorium maven.

Jurij Finczenko
źródło
5

Napotkałem ten sam problem i teraz został rozwiązany :) Wykonaj poniższe kroki, a błąd może dotyczyć wszystkiego, ale poniższe kroki sprawiają, że proces jest płynniejszy. Spędzam dużo czasu, aby znaleźć poprawkę.

1. Spróbuj ponownie uruchomić Eclipse (jeśli używasz Eclipse do zbudowania pliku JAR) -> W rzeczywistości pomogło to w moim problemie z prawidłowym eksportowaniem pliku JAR.

2.Po ponownym uruchomieniu zaćmienia sprawdź, czy zaćmienie jest w stanie rozpoznać główną klasę / metodę według projektu Java -> kliknij prawym przyciskiem myszy -> Uruchom jako -> Uruchom konfiguracje -> Główne -> kliknij przycisk Wyszukaj aby sprawdzić, czy twoje zaćmienie jest w stanie wyszukać twoją główną klasę w pliku JAR. -> Służy do sprawdzania, czy plik JAR będzie miał punkt wejścia do klasy głównej.

  1. Następnie wyeksportuj swój projekt Java Dynamic jako plik „Runnable JAR”, a nie plik JAR.

  2. W konfiguracji uruchamiania Java wybierz swoją główną klasę.

  3. Po wyeksportowaniu pliku jar użyj poniższego polecenia, aby wykonać. java -cp [Your JAR] .jar [pełny pakiet] .MainClass np .: java -cp AppleTCRuleAudit.jar com.apple.tcruleaudit.classes.TCRuleAudit

  4. Możesz napotkać nieobsługiwany błąd wersji Java. poprawka polega na zmianie java_home w profilu bash powłoki, aby pasował do wersji java użytej do skompilowania projektu w środowisku eclipse.

Mam nadzieję że to pomoże! Daj mi znać, jeśli nadal masz jakieś problemy.

KarthikPon
źródło
5

Miałem ten sam problem. Wiele z wymienionych tutaj rozwiązań nie dało mi całego obrazu, więc postaram się przedstawić streszczenie sposobu pakowania plików jar z wiersza poleceń .

  1. Jeśli chcesz mieć swoje .classpliki w paczkach, dodaj pakiet na początku .java.

    Test.java

    package testpackage;
    
    public class Test
    {
        ...
    }
  2. Aby skompilować kod z .classplikami kończącymi się na strukturze podanej przez nazwę pakietu, użyj:

    javac -d . Test.java

    -d .Sprawia, że kompilator utworzyć strukturę katalogów chcesz.

  3. Podczas pakowania .jarpliku musisz poinstruować procedurę dotyczącą słoika, jak ją spakować. Tutaj korzystamy z zestawu opcji cvfeP. Ma to na celu zachowanie struktury pakietu (opcja P), określenie punktu wejścia, aby plik manifestu zawierał znaczące informacje (opcja e). Opcja fpozwala określić nazwę pliku, opcja ctworzy archiwum, a opcja vustawia wyjście na pełne. Ważnymi rzeczami do odnotowania tutaj są Pi e.

    Potem pojawia się nazwa słoika, którego chcemy test.jar.

    Potem przychodzi punkt wejścia.

    A potem przychodzi, -C . <packagename>/aby pobrać pliki klas z tego folderu, zachowując strukturę folderów.

    jar cvfeP test.jar testpackage.Test -C . testpackage/
  4. Sprawdź .jarplik w programie zip. Powinien mieć następującą strukturę

    test.jar

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

    Plik MANIFEST.MF powinien zawierać następujące elementy

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

    Jeśli edytujesz manifest ręcznie, pamiętaj, aby zachować nowy wiersz na końcu, w przeciwnym razie Java go nie rozpozna.

  5. Wykonaj swój .jarplik za pomocą

    java -jar test.jar
CodeMonkey
źródło
1
Czwarty krok twojej odpowiedzi jest bardzo ważny! Mój manifest nie działał z powodu tej nowej linii na końcu, o której nie wiedziałem, że muszę go umieścić. Wszystkie odpowiedzi, które odwiedziłem na ten temat (dużo) nie wspominały o tym i jest to obowiązkowe dla każdego, kto nie używa maven, ant, gradle i tak dalej.
Maude
1
@ Maude dziękuję za opinię. Właśnie dlatego dodałem odpowiedź pogrubioną wskazówką nowego wiersza . Szukałem dni, dopóki się tego nie dowiedziałem, porównując z automatycznie wygenerowanym manifestem.
CodeMonkey
Hah, dzięki. Właśnie waliłem głową w tę nową linię.
Richard Thomas
5

Osobiście uważam, że wszystkie odpowiedzi tutaj źle rozumieją pytanie. Odpowiedź na to pytanie polega na tym, jak wiosenny rozruch buduje plik .jar. Wszyscy wiedzą, że Spring Boot konfiguruje taki manifest, który różni się od przypuszczenia każdego, że jest to standardowe uruchomienie .jar, którym może być lub nie:

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

Być może trzeba go wykonać org.springframework.boot.loader.JarLauncherna ścieżce klas?

djangofan
źródło
Brzmi obiecująco. Jak dokładnie dodajesz JarLauncher do ścieżki klasy?
MarkHu
4

Każdy plik wykonywalny jar powinien być uruchamiany poprzez kliknięcie lub uruchomienie przy użyciu wiersza polecenia, takiego jak java -jar app.jar (użyj „jeśli ścieżka jar zawiera spację” - tj. Java -jar „C: \ nazwa folderu \ app.jar”). Jeśli plik wykonywalny nie działa, co oznacza, że ​​nie został poprawnie utworzony.

Aby lepiej zrozumieć, wyodrębnij plik jar (lub wyświetl za pomocą dowolnego narzędzia, w systemie Windows 7-Zip jest fajny) i sprawdź plik w /META-INF/MANIFEST.MF. Jeśli znajdziesz jakikolwiek wpis

Klasa główna: twoja.nazwa_pliku.ClaaswithMain - wtedy jest w porządku, w przeciwnym razie musisz go podać.

Pamiętaj o dołączeniu pozycji klasy głównej do pliku MANIFEST.MF, sprawdź, gdzie ją zapisujesz!

Shekh Akther
źródło
4

Możesz po prostu wykonać ten krok. Utwórz plik jar za pomocą

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

Podczas uruchamiania pliku jar wystarczy uruchomić w ten sposób

 java -cp jarfile-name main-classname
Koneri
źródło
4

Być może nie utworzyłeś poprawnie pliku jar:

np .: brak opcji m przy tworzeniu słoika

Następujące prace:

jar -cvfm MyJar.jar Manifest.txt *.class
satheesh.v
źródło
4

Jeśli używasz wiersza poleceń do skompilowania .jar, możesz wskazać główny bez dodawania pliku manifestu. Przykład:

jar cfve app.jar TheNameOfClassWithMainMethod *.class

(param „e” robi to: TheNameOfClassWithMainMethod to nazwa klasy z metodami main () i app.jar - nazwa pliku wykonywalnego .jar i * .class - tylko wszystkie pliki klas do złożenia)

Andrey
źródło
3

Dla mnie ten błąd wystąpił po prostu dlatego, że zapomniałem powiedzieć Eclipse, że chciałem uruchomić plik jar, a nie zwykły plik jar biblioteki. Dlatego podczas tworzenia pliku jar w Eclipse upewnij się, że kliknąłeś prawy przycisk opcji

Neeraj Bhatnagar
źródło
3

Powyższe odpowiedzi były dla mnie tylko częściowo pomocne. java -cpbyło częścią odpowiedzi, ale potrzebowałem bardziej szczegółowych informacji o tym, jak zidentyfikować klasę do uruchomienia. Oto, co zadziałało dla mnie:

Krok 1: znajdź klasę, którą muszę uruchomić

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

Najważniejsze linie wyniku to:

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

Klasa App.class zawierała główną klasę do uruchomienia. Nie jestem w 100% pewien, czy zawsze możesz założyć, że klasa, której potrzebujesz, jest pierwsza, ale była dla mnie. Jeśli tak nie jest, wyobrażam sobie, że nie jest zbyt trudno użyć grep do wykluczenia wyników związanych z biblioteką, aby sprowadzić listę klas do rozsądnego rozmiaru.

Stamtąd było łatwo: po prostu używam tej ścieżki (minus sufiks „.class”):

java -cp /path/to/myjar.jar somepath/App
mwag
źródło
Nie zawsze jest to pierwsza klasa. Prawie nigdy. Wiersz polecenia powinien być java -cp ... somepackage.App.
user207421,
2

Ponieważ dodałeś plik MANIFEST.MF, myślę, że powinieneś rozważyć kolejność pól w tym pliku. Moja env to java version "1.8.0_91"

i mój MANIFEST.MF jak tutaj

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

Jednak, jak pokazano poniżej

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

//this run swing normally
Fan Yer
źródło
Co? Zamówienie jest nieistotne. Niejasne, co twierdzisz.
user207421,
2

(pierwszy post - więc może nie być czysty)

To jest moja poprawka dla OS X 11.6, programu Netbeans 8.2 opartego na Maven. Do tej pory moja aplikacja jest w 100% Netbeans - bez poprawek (tylko kilka ucieczek powłoki dla niemożliwego!).

Po wypróbowaniu większości odpowiedzi tutaj i gdzie indziej bezskutecznie powróciłem do sztuki „używaj tego, co działa”.

Najlepsza odpowiedź tutaj ( olivier-refalo thanx) wyglądała na właściwe miejsce na rozpoczęcie, ale nie pomogła.

Patrząc na inne projekty, które się sprawdziły, zauważyłem niewielkie różnice w liniach manifestu:

  1. addClasspath, classpathPrefix były nieobecne (usunąłem je)
  2. mainClass brakowało „com”. (użył NB -> Właściwości projektu-> Uruchom-> Główna klasa-> Przeglądaj, aby określić)

Nie jestem pewien, dlaczego (jestem tylko 3 miesiące do java) lub jak, ale mogę tylko powiedzieć, że to zadziałało.

Oto zastosowany zmodyfikowany blok manifestu:

    <manifest>
        <mainClass>mypackage.MyClass</mainClass>
    </manifest>
MichaelT
źródło
2

Znalazłem nowe rozwiązanie złego generowania manifestów!

  1. Otwórz plik jar za pomocą edytora zip, takiego jak WinRAR
  2. Kliknij na META-INF

  3. Dodaj lub edytuj

    • Dodaj:

      • Utwórz plik tekstowy o nazwie MANIFEST.MF w folderze o nazwie META-INF i dodaj następujący wiersz:

        • Wersja manifestu: 1.0
        • Główna klasa: package.ex.com.views.mainClassName
      • Zapisz plik i dodaj go do pliku zip

    • Edytować:

      • Przeciągnij plik, zmodyfikuj plik MANIFEST.MF, aby dodać poprzednią linię
  4. Otwórz cmd i wpisz: java -jar c: /path/JarName.jar

Teraz powinno działać dobrze!

Dave Beauchesne
źródło
2

większość rozwiązań nie działała dla mnie, ale mój instruktor pomógł mi, chciałbym podzielić się jego rozwiązaniem tutaj użyłem terminalu Kali Linux, ale powinno być dobrze we wszystkich debianach

javac *.java
nano MANIFEST.MF

w typie pliku

Main-Class: Main lub jakikolwiek inny główny plik (pamiętaj, aby dodać nazwę pakietu, jeśli istnieje)

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

teraz, aby uruchomić użycie pliku

java -jar new.jar

lub możesz przejść do właściwości pliku i sprawdzić

Pozwól na wykonanie pliku jako programu

kliknij dwukrotnie

pomogło mi, a większość powyższych odpowiedzi nie


źródło
1

Możesz mieć taki sam problem jak ja. Po utworzeniu pliku .jar napisz jar xf app.jar META-INF/MANIFEST.MF. Spowoduje to utworzenie kopii pliku do bieżącego katalogu, aby można go było przeczytać. Jeśli mówi tylko coś takiego:

Wersja manifestu: 1.0

Utworzony przez: 1.8.0_51 (Oracle Corporation)

i nie zawiera deklaracji „klasy głównej”, więc myślę, że znalazłeś swój problem.

Nie wiem jednak, jak to rozwiązać. Sprawdziłem inne osoby z tymi samymi / podobnymi problemami na StackOverflow i nie mogłem znaleźć odpowiedzi. Jednak dzięki tym informacjom możesz być może uzyskać lepszą pomoc (biorąc pod uwagę fakt, że masz ten sam problem co ja).

Edycja: Próbowałem z plikiem manifestu, ale nie udało mi się go uruchomić, ale moim błędem było nazwanie tylko jednej z klas podczas tworzenia pliku jar. Zamiast tego napisałem * .class i teraz działa.

Chociaż nie wiem, dlaczego istnieje potrzeba utworzenia pliku manifestu. Ale chyba wszystko jest w porządku, dopóki działa.

Żandarm
źródło
1

Miałem ten problem i rozwiązałem go ostatnio, robiąc to w Netbeans 8 (patrz obrazek poniżej):

Właściwości projektu Netbeans

  1. przejdź do właściwości swojego projektu.
  2. kliknij Uruchom .
  3. określ główną klasę swojego projektu za pomocą opcji Przeglądaj .
  4. buduj i uruchom plik Jar.
Abdelsalam Shahlol
źródło