1151 votes

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

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

java -jar "app.jar"

Je reçois le message suivant :

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

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

0 votes

Recherchez les méthodes principales ; vous ne pouvez pas vous fier aux noms des classes.

2 votes

Je sais, mais comme je n'ai que des fichiers .class, je ne peux pas vraiment voir les méthodes. Mais est-ce que je peux ?

0 votes

Vous n'êtes pas vraiment en train de taper les citations, n'est-ce pas ? Quoi qu'il en soit, il existe plusieurs façons de voir les méthodes, dont l'utilisation de javap . Vous pourriez vouloir le désarrimer et vérifier qu'il n'y a pas de manifeste.

1127voto

Olivier Refalo Points 12606

D'abord, c'est un peu bizarre, de vous voir courir java -jar "app" et non java -jar app.jar

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

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

Main-Class: com.mypackage.MyClass

com.mypackage.MyClass est la classe qui détient le public static void main(String[] args) point d'entrée.

Notez qu'il existe plusieurs façons d'y parvenir, que ce soit avec le 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 qu'il s'agit uniquement de la définition du plugin, et non de la version complète de l'application pom.xml :

Dernière documentation sur ce plugin : voir https://maven.apache.org/plugins/maven-jar-plugin/

<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 Fourmi l'extrait 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'
        )
    }
}

15 votes

Dans Ant son <manifest><attribute name="Main-Class" value="com.mypackage.MyClass"/></manifest> dans l'élément <jar>.

2 votes

Merci. Je voulais juste ajouter que vous pouvez copier les dépendances dans le dossier lib en utilisant ceci : stackoverflow.com/a/996915/1121497 . Puisque le classpath inclut ce lib alors il vous suffit d'exécuter le jar avec java -jar myproject.jar et il trouvera les dépendances.

5 votes

Comment "mettre en jar un fichier appelé META-INF/MANIFEST.MF" ? J'ai un .jar d'un côté et un .MF de l'autre, comment puis-je les lier ensemble ? J'ai mis le manifest dans le même dossier que le .jar mais ça ne marche pas, j'ai toujours le problème !

325voto

Jesper Points 65733

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

Le site -jar L'option ne fonctionne que si le fichier JAR est un fichier JAR exécutable, ce qui signifie qu'il doit avoir un fichier de manifeste avec un Main-Class dans celui-ci. Voir Empaquetage des programmes dans les fichiers JAR pour apprendre comment créer un JAR exécutable.

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

java -cp app.jar com.somepackage.SomeClass

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

4 votes

merci pour votre réponse, mais votre solution ne fonctionne que si je connais le nom de la classe qui contient la méthode main. Et c'était une faute de frappe... C'était censé être "app.jar". Mais comment expliquez-vous qu'il fonctionne sur d'autres systèmes en double cliquant simplement sur le fichier ?

0 votes

S'il s'agit bien d'un JAR exécutable, vous pouvez extraire le fichier manifeste (il se trouve dans le fichier META-INF dans le fichier JAR). Il doit contenir un Main-Class qui vous donne le nom de la classe principale.

0 votes

S'il ne fonctionne pas sur un système, alors ce système a peut-être une version de Java trop ancienne. Si le JAR est par exemple compilé avec Java 7, vous ne pouvez pas l'exécuter sur un système qui a Java 6 ou plus ancien.

64voto

Sasanka Panguluri Points 1405

C'est parce que Java ne trouve pas l'attribut Main dans le fichier MANIFEST.MF. L'attribut Main est nécessaire pour indiquer à Java quelle classe il doit 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 regarder ce qu'il y a dans un fichier jar ? Ouvrez le fichier jar avec WinRAR.

L'attribut principal dans le fichier MANIFEST.MF ressemble à ceci :

Main-Class: <packagename>.<classname>

Vous obtenez cette erreur "no main manifest attribute" lorsque cette ligne est absente du fichier MANIFEST.MF.

C'est un véritable gâchis que de spécifier cet attribut dans le fichier MANIFEST.MF.

Mise à jour : Je viens de trouver un moyen très efficace de spécifier le point d'entrée de l'application dans eclipse. Lorsque vous dites Export,

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

32voto

Dave Points 226

Pour maven, c'est 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>

Santé...

0 votes

J'ai trouvé que cela fonctionnait mais je devais exécuter en tant que mvn package shade:shade juste en train de courir mvn package n'a pas déclenché l'exécution du plugin d'ombrage.

28voto

Burhan ARAS Points 664

Essayez cette commande pour inclure le jar :

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

1 votes

Une façon est d'inclure la classe principale dans le fichier pom.xml et d'utiliser la commande java -jar, l'autre est d'utiliser la commande java -cp.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X