web-dev-qa-db-fra.com

Impossible d'exécuter le fichier jar: "aucun attribut de manifeste principal"

J'ai installé une application, lorsque j'essaie de l'exécuter (c'est un fichier jar exécutable), rien ne se passe. Quand je le lance depuis la ligne de commande avec:

Java -jar "app.jar"

Je reçois le message suivant:

pas d'attribut manifeste principal, dans "app.jar"

Normalement, si j'avais créé le programme moi-même, j'aurais ajouté un attribut de classe principal au fichier manifeste. Mais dans ce cas, comme le fichier provient d'une application, je ne peux pas le faire. J'ai aussi essayé d'extraire le pot pour voir si je pouvais trouver la classe principale, mais il y en a beaucoup et aucune ne contient le mot "main" dans son nom. Il doit y avoir un moyen de résoudre ce problème car le programme fonctionne correctement sur d’autres systèmes.

820
Ewoud

Tout d’abord, c’est bizarre de voir que vous exécutez _Java -jar "app"_ et non _Java -jar app.jar_

Deuxièmement, pour créer un fichier jar exécutable ... vous devez créer un fichier jar nommé META-INF/MANIFEST.MF.

le fichier lui-même devrait avoir (au moins) cette doublure:

_Main-Class: com.mypackage.MyClass
_

Où _com.mypackage.MyClass_ est la classe contenant le point d'entrée principal public statique (String [] args) .

Notez qu'il existe plusieurs façons de le faire avec la CLI, Maven, Ant ou Gradle:

Pour CLI, la commande suivante fera l'affaire: (tks @ dvvrt ) _jar cmvf META-INF/MANIFEST.MF <new-jar-filename>.jar <files to include>_

Pour Maven , quelque chose comme l'extrait suivant devrait faire l'affaire. Notez que ceci est seulement la définition du plugin, pas la totalité 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>
_

(Choisissez un <version> approprié à votre projet.)

Pour Ant , l'extrait de code ci-dessous devrait vous aider:

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

Crédits Michael Niemand -

Pour Gradle :

_plugins {
    id 'Java'
}

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

Cela aurait dû être Java -jar app.jar au lieu de Java -jar "app".

L'option -jar ne fonctionne que si le fichier JAR est un fichier JAR exécutable, ce qui signifie qu'il doit avoir un fichier manifeste avec un attribut Main-Class. Voir Programmes d'empaquetage dans des fichiers JAR pour savoir comment créer un fichier JAR exécutable.

Si ce n'est pas un fichier JAR exécutable, vous devez exécuter le programme avec quelque chose comme:

Java -cp app.jar com.somepackage.SomeClass

com.somepackage.SomeClass est la classe qui contient la méthode main pour exécuter le programme. (Ce que la classe est dépend du programme, il est impossible de dire à partir des informations que vous avez fournies).

246
Jesper

Vous pouvez également utiliser le plugin maven-Assembly, comme indiqué dans l'exemple ci-dessous:

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

Dans cet exemple, tous les fichiers de dépendance spécifiés dans la section seront automatiquement inclus dans votre fichier .jar. Notez que jar-with-dependencies doit être littéralement mis comme, ne pas être remplacé par les noms de fichier jar que vous souhaitez inclure.

106
CodeBrew

En effet, Java ne trouve pas l'attribut Main dans le fichier MANIFEST.MF. L'attribut Main est nécessaire pour indiquer à Java la classe à utiliser comme point d'entrée de l'application. Dans le fichier jar, le fichier MANIFEST.MF se trouve dans le dossier META-INF. Vous vous demandez comment vous pourriez regarder le contenu d'un fichier jar? Ouvrez le fichier jar avec WinRAR.

L'attribut principal à l'intérieur de MANIFEST.MF ressemble à ceci:

Main-Class: <packagename>.<classname>

Vous obtenez cette erreur "aucun attribut manifeste principal" lorsque cette ligne est manquante dans le fichier MANIFEST.MF.

C'est vraiment un désordre énorme de spécifier cet attribut dans le fichier MANIFEST.MF.

Mise à jour: je viens de trouver un moyen vraiment pratique de spécifier le point d'entrée de l'application dans Eclipse. Quand vous dites exporter,

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

58
Sasanka Panguluri

La réponse Gradle consiste à ajouter un paramètre jar/manifeste/attributs comme ceci:

apply plugin: 'Java'

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

Pour maven, voici ce qui a résolu le problème (pour moi, pour une base de code Veetle sur 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>

À votre santé...

25
Dave

Essayez cette commande pour inclure le pot:

Java -cp yourJarName.jar your.package..your.MainClass
24
Burhan ARAS

J'ai eu ce problème lors de la création d'un pot en utilisant IntelliJ IDEA. Voir cette discussion .

Ce qui a résolu le problème pour moi a été de recréer l'artefact jar, en choisissant JAR> À partir de modules avec dépendances, mais en n'acceptant pas le répertoire par défaut pour META-INF/MANIFEST.MF. Changez-le de -/src/main/Java à -/src/main/resources.

Sinon, il incluait un fichier manifeste dans le fichier jar, mais pas celui dans -/src/main/Java qu'il devrait avoir.

23
morningstar

J'ai eu le même problème. en ajoutant les lignes suivantes au fichier pom, cela a fonctionné. Le plugin assurera le processus de construction de votre application avec toutes les étapes nécessaires.

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

Pour moi, aucune des réponses n'a vraiment aidé - j'ai eu le fichier manifeste à la bonne place, contenant la classe principale et tout. Voici ce qui m'a fait trébucher:

Avertissement: le fichier texte à partir duquel vous créez le manifeste doit se terminer par une nouvelle ligne ou un retour à la ligne. La dernière ligne ne sera pas analysée correctement si elle ne se termine pas par une nouvelle ligne ou un retour à la ligne.

( source ). L'ajout d'une nouvelle ligne à la fin du manifeste l'a corrigé.

13
eis

Si vous utilisez Maven, incluez ce qui suit dans le 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>
9
shuang

J'ai la même erreur tout à l'heure. Si vous utilisez gradle, ajoutez simplement le suivant dans votre gradle.build:

apply plugin: 'Java'

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

com.company.project.MainClass chemin d'accès à votre classe avec la méthode public static void main(String[] args).

9
Binakot

J'ai eu le même problème aujourd'hui. Mon problème a été résolu en déplaçant META-INF dans le dossier des ressources.

8
RegUser

Si le fichier jar ne suit pas règles , il ne s'agit pas d'un fichier jar exécutable.

6
John M

Je suis confronté au même problème et il est corrigé maintenant :) Il suffit de suivre les étapes ci-dessous et l'erreur peut concerner n'importe quoi, mais les étapes ci-dessous facilitent le processus. Je passe beaucoup de temps à trouver la solution.

1.Essayez de redémarrer Eclipse (si vous utilisez Eclipse pour créer un fichier JAR) -> En fait, cela a aidé mon problème à exporter correctement le fichier JAR.

2.Après le redémarrage d’Eclipse, essayez de voir si votre Eclipse est capable de reconnaître la classe/méthode principale par votre projet Java -> cliquez à droite -> Exécuter en tant que -> Exécuter les configurations -> Principal. -> cliquez sur le bouton Rechercher pour voir si votre Eclipse est capable de rechercher votre classe principale dans le fichier JAR. -> C'est pour la validation que le fichier JAR aura le point d'entrée dans la classe principale.

  1. Ensuite, exportez votre projet Java Dynamic en tant que fichier "Runnable JAR" et non pas JAR.

  2. Dans la configuration de lancement de Java, choisissez votre classe principale.

  3. Une fois le fichier jar exporté, utilisez la commande ci-dessous pour l'exécuter. Java -cp [Votre JAR] .jar [package complet] .MainClass Exemple: Java -cp AppleTCRuleAudit.jar com.Apple.tcruleaudit.classes.TCRuleAudit

  4. Vous pourriez être confronté à l'erreur de version Java non prise en charge. le correctif consiste à modifier le Java_home dans votre profil bash Shell afin qu'il corresponde à la version Java utilisée pour compiler le projet dans Eclipse.

J'espère que cela t'aides! S'il vous plaît laissez-moi savoir si vous avez encore des problèmes.

5
Karthik Pon

J'ai eu le même problème. Beaucoup des solutions mentionnées ici ne m'ont pas donné une image complète, je vais donc essayer de vous donner un résumé de la procédure à suivre pour compresser les fichiers jar à partir de la ligne de commande.

  1. Si vous voulez avoir vos fichiers .class dans des packages, ajoutez-le au début du fichier .Java.

    Test.Java

    package testpackage;
    
    public class Test
    {
        ...
    }
    
  2. Pour compiler votre code avec vos fichiers .class, vous obtenez la structure donnée par le nom du paquet, utilisez:

    javac -d . Test.Java
    

    Le -d . permet au compilateur de créer la structure de répertoires souhaitée.

  3. Lorsque vous empaquetez le fichier .jar, vous devez indiquer à la routine jar comment emballer le fichier. Ici, nous utilisons l’option set cvfeP. Ceci est pour conserver la structure du package (option P), spécifier le point d'entrée afin que le fichier manifeste contienne des informations utiles (option e) . L'option f vous permet de spécifier le nom du fichier, l'option c crée une archive et l'option v définit le résultat comme détaillé. Les points importants à noter ici sont P et e.

    Vient ensuite le nom du pot que nous voulons test.jar.

    Vient ensuite le point d'entrée.

    Et puis vient -C . <packagename>/ pour obtenir les fichiers de classe de ce dossier, en préservant la structure du dossier.

    jar cvfeP test.jar testpackage.Test -C . testpackage/
    
  4. Vérifiez votre fichier .jar dans un programme Zip. Il devrait avoir la structure suivante

    test.jar

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

    MANIFEST.MF doit contenir les éléments suivants

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

    Si vous éditez votre manifeste à la main veillez à conserver la nouvelle ligne à la fin sinon Java ne le reconnaît pas.

  5. Exécutez votre fichier .jar avec

    Java -jar test.jar
    
4
CodeMonkey

Tout fichier jar exécutable Doit être exécuté en cliquant ou en utilisant la commande Invite comme Java -jar app.jar (utilisez "si le chemin du fichier jar contient de l'espace" - c'est-à-dire Java -jar "C :\nom du dossier\app.jar "). Si votre fichier jar exécutable n'est pas en cours d'exécution, cela signifie qu'il n'est pas créé correctement.

Pour une meilleure compréhension, extrayez le fichier jar (ou affichez-le à l'aide de n'importe quel outil, car Windows 7-Zip est un fichier Nice) et vérifiez le fichier sous /META-INF/MANIFEST.MF. Si vous trouvez une entrée comme

Main-Class: your.package.name.ClaaswithMain - alors tout va bien, sinon vous devez le fournir.

Soyez conscient de l'ajout de l'entrée Main-Class sur le fichier MANIFEST.MF, vérifiez où vous l'enregistrez!

4
Shekh Akther

Vous n'avez peut-être pas créé le fichier jar correctement:

ex: option m manquante dans la création du pot

Les oeuvres suivantes:

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

Personnellement, je pense que toutes les réponses ici sont mal comprendre la question. La réponse à cette question réside dans la différence entre Spring-Boot et le .jar. Tout le monde sait que Spring Boot configure un manifeste comme celui-ci, qui varie d'un utilisateur à l'autre assomption qu'il s'agit d'un lancement standard .jar, qu'il s'agisse ou non de ce qui suit:

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

Peut-être qu'il doit être exécuté avec org.springframework.boot.loader.JarLauncher sur le classpath?

4
djangofan

Vous pouvez simplement suivre cette étape Créez un fichier JAR en utilisant

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

Tout en exécutant le fichier jar simple, exécutez comme ceci

 Java -cp jarfile-name main-classname
4
Koneri

Pour moi, cette erreur s’est produite simplement parce que j’ai oublié de dire à Eclipse que je voulais un fichier jar exécutable et non un simple fichier jar de bibliothèque. Ainsi, lorsque vous créez le fichier jar dans Eclipse, assurez-vous de cliquer sur le bouton radio droit.

3
Neeraj Bhatnagar

Les réponses ci-dessus ne m'ont été que partiellement utiles. Java -cp faisait partie de la réponse, mais j'avais besoin d'informations plus spécifiques sur la manière d'identifier la classe à exécuter. Voici ce qui a fonctionné pour moi:

Étape 1: trouvez le cours dont j'ai besoin

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

Les premières lignes du résultat sont:

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

App.class contenait la classe principale à exécuter. Je ne suis pas sûr à 100% si vous pouvez toujours supposer que le cours dont vous avez besoin est le premier, mais c'était pour moi. Si ce n'est pas le cas, j'imagine qu'il n'est pas trop difficile d'utiliser grep pour exclure les résultats liés aux bibliothèques afin de réduire la liste des classes à une taille raisonnable.

À partir de là, c’était simple: j’utilise ce chemin (sans le suffixe ".class"):

Java -cp /path/to/myjar.jar somepath/App
3
mwag

Puisque vous avez ajouté MANIFEST.MF, je pense que vous devriez considérer l'ordre de Field dans ce fichier. Mon envoi est Java version "1.8.0_91"

et mon MANIFEST.MF comme ici

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

Cependant, comme indiqué ci-dessous,

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

//this run swing normally
2
Fan Yer

(premier post - donc ça risque de ne pas être propre)

Ceci est ma solution pour OS X 11.6, le programme Netbeans 8.2 basé sur Maven. Jusqu'à présent, mon application est 100% Netbeans - pas de peaufinage (seulement quelques échappements de Shell pour l'impossible!).

Ayant essayé la plupart des réponses ici et ailleurs sans succès, je suis revenu à l'art de "utiliser ce qui fonctionne".

La meilleure réponse ici ( olivier-refalo thanx) semblait être le bon endroit pour commencer mais n'a pas aidé.

En regardant d'autres projets qui ont fonctionné, j'ai remarqué quelques différences mineures dans les lignes du manifeste:

  1. addClasspath, classpathPrefix étaient absents (les ont supprimés)
  2. mainClass manquait le "com". (Utilisé le NB -> Propriétés du projet-> Exécuter-> Classe principale-> Parcourir pour spécifier)

Je ne sais pas pourquoi (je ne suis que depuis 3 mois en Java) ou comment, mais je peux seulement dire que cela a fonctionné.

Voici juste le bloc manifeste modifié utilisé:

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

J'ai trouvé une nouvelle solution à la mauvaise génération de manifeste!

  1. Ouvrez le fichier jar avec un éditeur Zip tel que WinRAR
  2. Cliquez sur pour META-INF

  3. Ajouter ou modifier

    • Ajouter:

      • Créez un fichier texte appelé MANIFEST.MF dans un dossier appelé META-INF et ajoutez la ligne suivante:

        • Manifest-Version: 1.0
        • Classe principale: package.ex.com.views.mainClassName
      • Enregistrez le fichier et ajoutez-le au zip

    • Modifier:

      • Faites glisser le fichier pour modifier MANIFEST.MF pour ajouter la ligne précédente
  4. Ouvrez cmd et tapez: Java -jar c: /path/JarName.jar

Cela devrait bien fonctionner maintenant!

2
Dave Beauchesne

la plupart des solutions ne fonctionnaient pas pour moi, mais mon instructeur m'a aidé. J'aimerais partager sa solution ici. J'utilisais le terminal linux kali, mais cela devrait bien se passer dans tout Debian.

javac *.Java
nano MANIFEST.MF

dans le type de fichier

Main-Class: Main ou quel que soit votre nom de fichier principal (assurez-vous d'ajouter le nom du paquet s'il existe)

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

maintenant pour utiliser le fichier

Java -jar new.jar

ou vous pouvez aller aux propriétés de fichier et vérifier

Autoriser l'exécution du fichier en tant que programme

double-cliquez dessus

cela m'a aidé alors que la plupart des réponses ci-dessus ne

1
user10356724

Vous pourriez avoir le même problème que moi. Après avoir créé votre fichier .jar, écrivez jar xf app.jar META-INF/MANIFEST.MF. Cela créera une copie du fichier dans votre répertoire actuel afin que vous puissiez le lire. Si cela ne dit que quelque chose comme:

Manifest-Version: 1.0

Créé-par: 1.8.0_51 (Oracle Corporation)

et ne contient pas la déclaration "Main-Class", alors je pense que vous avez trouvé votre problème.

Je ne sais pas comment le résoudre, cependant. J'ai vérifié d'autres personnes avec des problèmes identiques/similaires sur StackOverflow et je n'ai pas trouvé de réponse. Cependant, avec cette information, vous pouvez peut-être obtenir une meilleure aide (étant donné que vous avez le même problème que moi).

Edit: j'ai essayé avec un fichier manifeste mais je ne l'ai pas fait fonctionner, mais mon erreur a été de ne nommer qu'une des classes lors de la création du fichier jar. J'ai écrit * .class à la place et cela fonctionne maintenant.

Bien que je ne sache pas pourquoi il est nécessaire de créer un fichier manifeste. Mais je suppose que ça va tant que ça marche.

1
Gendarme

Si vous utilisez la ligne de commande pour assembler .jar, il est possible de pointer sur le fichier principal sans ajouter de fichier manifeste. Exemple:

jar cfve app.jar TheNameOfClassWithMainMethod *.class

(le param "e" fait cela: TheNameOfClassWithMainMethod est un nom de la classe avec la méthode main () et app.jar - nom de l'exécutable .jar et * .class - juste tous les fichiers de classes à assembler)

1
Andrey

J'ai eu ce problème et je l'ai résolu récemment en faisant cela dans Netbeans 8 (Reportez-vous à l'image ci-dessous):

Netbeans project properties

  1. allez à propriétés de votre projet.
  2. cliquez sur Run.
  3. spécifiez la classe principale de votre projet en utilisant parcourir.
  4. build et run le fichier Jar.
1
Abdelsalam Shahlol

Juste pour préciser un point à propos de

Main-Class: <packagename>.<classname>

Si vous n'avez pas de paquet, vous devez ignorer cette partie, comme ceci:

Main-Class: <classname>
1
Reihan_amn

vérifiez si votre fichier jar dans MANIFEST.MF Main-Class est disponible ou non

premier.Java

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

Avant:

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

Après:

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
0
KARTHIKEYAN.A

J'ai eu un problème similaire à vous, en dessous d'une syntaxe pour créer avec succès .war Fichier: -

jar {cvf} [fichier-jar] [fichier-manifeste]

manifeste Lors de la création (c) ou de la mise à jour (u) d'un fichier JAR, l'opérande manifeste définit les fichiers manifestes préexistants avec les noms et les valeurs des attributs à inclure dans MANIFEST.MF dans le fichier JAR. L'opérande manifeste doit être spécifié si l'option f est présente '[ 1 ]'.

Pour créer un fichier manifeste, vous devez définir une valeur pour certains attributs. Vous pouvez insérer un astérisque après le nom du fichier (.WAR) pour éviter de créer un fichier manifeste: -

jar -cvf foo.war *

Pour être honnête avec vous, je ne sais pas si c'est une pratique exemplaire, mais cela me permet de faire le travail :).

0
M.87

Vous avez trouvé une solution qui pourrait vous aider dans de telles situations, étant donné que vous avez simplement besoin d'un bocal qui fonctionne, ce que vous faites dans la plupart des cas. Si votre application est exécutée dans Intellij Idea, suivez ces étapes: 1) Accédez aux paramètres du module, puis aux artefacts, puis ajoutez un fichier jar et définissez la classe principale 2). Ensuite, accédez à Générer dans le menu et cliquez sur "Générer un artefact" pour obtenir le fichier jar. .

Cela a fonctionné même lorsque j'ai changé le dossier source et utilisé scala au lieu de Java.

0
Ritesh Tyagi