web-dev-qa-db-fra.com

Construire un pot exécutable avec Maven?

J'essaie de générer un fichier jar exécutable pour un petit projet domestique appelé "logmanager" à l'aide de maven, comme ceci:

Comment créer un fichier JAR exécutable avec des dépendances à l'aide de Maven?

J'ai ajouté l'extrait de code indiqué ici dans pom.xml et j'ai exécuté mvn Assembly: assembly. Il génère deux fichiers jar dans logmanager/target: logmanager-0.1.0.jar et logmanager-0.1.0-jar-with-dependencies.jar. Je reçois une erreur lorsque je double-clique sur le premier pot:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Une erreur légèrement différente lorsque je double-clique sur le fichier jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

J'ai copié et collé le chemin et le nom de la classe et vérifié l'orthographe dans le POM. Ma classe principale démarre correctement à partir d'une configuration de lancement Eclipse. Quelqu'un peut-il m'aider à comprendre pourquoi mon fichier jar ne s'exécute pas? Aussi, pourquoi y a-t-il deux bocaux pour commencer? Faites-moi savoir si vous avez besoin de plus d'informations.

Voici le pom.xml complet, pour référence:

<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gorkwobble</groupId>
  <artifactId>logmanager</artifactId>
  <name>LogManager</name>
  <version>0.1.0</version>
  <description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <!-- nothing here -->
        </plugin>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-Assembly-plugin</artifactId>
            <version>2.2-beta-4</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
    </plugins>
  </build>
  <dependencies>
    <!-- commons-lang -->
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
    </dependency> 

    <!-- Quartz scheduler -->
    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.3</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons collections -->
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.1</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>
    <!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
      <scope>runtime</scope>
    </dependency>

    <!-- junitx test assertions -->
    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>

    <!-- junit dependency; FIXME: make this a separate POM -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.1</version>
    </dependency>

  </dependencies>
  <dependencyManagement>
  </dependencyManagement>
</project>
117
RMorrisey

En fait, je pense que la réponse donnée dans la question que vous avez mentionnée est juste fausse ( MISE À JOUR - 20101106: quelqu'un l’a corrigé, cette réponse fait référence à la version précédant la modification ), ce qui explique , au moins partiellement, pourquoi vous rencontrez des problèmes.


Il génère deux fichiers jar dans logmanager/target: logmanager-0.1.0.jar et logmanager-0.1.0-jar-with-dependencies.jar.

Le premier est le fichier JAR du module logmanager généré au cours de la phase package par jar:jar (car le module a un conditionnement de type jar). Le second est l'assembly généré par Assembly:assembly et doit contenir les classes du module actuel et ses dépendances (si vous avez utilisé le descripteur jar-with-dependencies).

Je reçois une erreur lorsque je double-clique sur le premier pot:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Si vous avez appliqué la configuration suggérée du lien posté comme référence, vous avez configuré le plug-in jar pour produire un artefact exécutable, à peu près comme ceci:

  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

Donc, logmanager-0.1.0.jar est bien exécutable mais 1. ce n'est pas ce que vous voulez (car il n'a pas toutes les dépendances) et 2. il ne contient pas com.gorkwobble.logmanager.LogManager (c'est ce que dit l'erreur, vérifiez le contenu du pot).

Une erreur légèrement différente lorsque je double-clique sur le fichier jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Encore une fois, si vous avez configuré le plugin Assembly comme suggéré, vous avez quelque chose comme ceci:

  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-Assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

Avec cette configuration, logmanager-0.1.0-jar-with-dependencies.jar contient les classes du module actuel et ses dépendances mais, en fonction de l'erreur, son META-INF/MANIFEST.MF ne ne contient pas d'entrée Main-Class (probablement pas le même MANIFEST.MF que dans logmanager-0.1.0.jar). Le fichier jar n'est en réalité pas , ce qui, encore une fois, n'est pas ce que vous voulez.


Donc, ma suggestion serait de supprimer l'élément configuration du maven-jar-plugin et de configurer le maven-Assembly-plugin comme ceci:

  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.2</version>
    <!-- nothing here -->
  </plugin>
  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-Assembly-plugin</artifactId>
    <version>2.2-beta-4</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Bien sûr, remplacez org.sample.App par la classe que vous voulez faire exécuter. Petit bonus, j'ai lié Assembly:single à la phase package afin que vous n'ayez plus à exécuter Assembly:assembly. Il suffit de lancer mvn install et l'assemblage sera produit lors de la construction standard.

Donc, veuillez mettre à jour votre fichier pom.xml avec la configuration donnée ci-dessus et lancer mvn clean install. Ensuite, cd dans le répertoire target et essayez à nouveau:

Java -jar logmanager-0.1.0-jar-with-dependencies.jar

Si vous obtenez une erreur, veuillez mettre à jour votre question et publier le contenu du fichier META-INF/MANIFEST.MF ainsi que la partie correspondante de votre pom.xml (éléments de configuration des plugins). Aussi s'il vous plaît poster le résultat de:

Java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager

pour démontrer que cela fonctionne bien sur la ligne de commande (peu importe ce que dit Eclipse).

EDIT: Pour Java 6, vous devez configurer le plug-in maven-compiler. Ajoutez ceci à votre pom.xml:

  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
239
Pascal Thivent

La réponse de Pascal Thivent m'a aussi aidé. Mais si vous gérez vos plugins dans l'élément <pluginManagement>, vous devez définir à nouveau l'assembly en dehors de la gestion du plugin, sinon les dépendances ne sont pas contenues dans le fichier jar si vous exécutez mvn install.

<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <build>
        <pluginManagement>
            <plugins>

                <plugin>
                    <groupId>org.Apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.Apache.maven.plugins</groupId>
                    <artifactId>maven-Assembly-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>main.App</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-Assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

            </plugins>

        </pluginManagement>

        <plugins> <!-- did NOT work without this  -->
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-Assembly-plugin</artifactId>
            </plugin>
        </plugins>

    </build>


    <dependencies>
       <!--  dependencies commented out to shorten example -->
    </dependencies>

</project>
14
mike

Si vous ne souhaitez pas exécuter d'objectif Assembly sur un package, vous pouvez utiliser la commande suivante:

mvn package Assembly:single

Ici package est un mot clé.

5
leonidv

Faites un clic droit sur le projet et donnez maven build, maven clean, maven générer des ressources et installer maven. Le fichier jar sera généré automatiquement.

0
dolly doll