web-dev-qa-db-fra.com

Comment mettre tous les fichiers JAR requis dans un dossier de bibliothèque dans le fichier JAR final avec Maven?

J'utilise Maven dans mon application autonome et je souhaite intégrer toutes les dépendances de mon fichier JAR dans un dossier de bibliothèque, comme indiqué dans l'une des réponses suivantes:

Comment créer un fichier JAR exécutable avec des dépendances utilisant Maven?

Je souhaite que mon fichier JAR final ait un dossier de bibliothèque contenant les dépendances sous forme de fichiers JAR, contrairement à ce que le maven-shade-plugin met les dépendances sous la forme de dossiers tels que la hiérarchie Maven dans le dossier .m2.

En fait, la configuration actuelle fait ce que je veux, mais le chargement des fichiers JAR lorsque je lance l'application pose un problème. Je ne peux pas charger les cours.

Voici ma configuration:

<plugins>

    <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
            <execution>
                <id>copy-dependencies</id>
                <phase>prepare-package</phase>
                <goals>
                    <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                    <outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
                    <overWriteReleases>false</overWriteReleases>
                    <overWriteSnapshots>false</overWriteSnapshots>
                    <overWriteIfNewer>true</overWriteIfNewer>
                </configuration>
            </execution>
        </executions>
    </plugin>

    <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>lib/</classpathPrefix>
                    <mainClass>com.myapp.MainClass</mainClass>
                </manifest>
            </archive>
        </configuration>
    </plugin>

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

    <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
            <execution>
                <id>install</id>
                <phase>install</phase>
                <goals>
                    <goal>sources</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

    <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.5</version>
        <configuration>
            <encoding>UTF-8</encoding>
        </configuration>
    </plugin>

</plugins>

Le projet fonctionne correctement à partir d’Eclipse et les fichiers JAR sont placés dans le dossier de la bibliothèque à l’intérieur de mon fichier JAR final comme je le souhaite, mais lors de l’exécution du fichier JAR final à partir du dossier cible, j’obtiens toujours ClassNotFoundException:

Exception in thread "main" Java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
Caused by: Java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext
        at Java.net.URLClassLoader$1.run(Unknown Source)
        at Java.security.AccessController.doPrivileged(Native Method)
        at Java.net.URLClassLoader.findClass(Unknown Source)
        at Java.lang.ClassLoader.loadClass(Unknown Source)
        at Sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at Java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: com.myapp.MainClass. Program will exit.

Comment puis-je réparer cette exception?

93
Mahmoud Saleh

en suivant ce lien:

Comment: Eclipse Maven installer le build jar avec dépendances

j'ai découvert que ce n'est pas une solution viable parce que le chargeur de classes ne charge pas les fichiers JAR à l'intérieur des fichiers JAR. Je pense donc que je vais décompresser les dépendances à l'intérieur du fichier JAR.

5
Mahmoud Saleh

Ce qui suit est ma solution. Testez-le si cela fonctionne pour vous:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <!-- <classpathPrefix>lib</classpathPrefix> -->
                <!-- <mainClass>test.org.Cliente</mainClass> -->
            </manifest>
            <manifestEntries>
                <Class-Path>lib/</Class-Path>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

Le premier plug-in place toutes les dépendances dans le dossier target/classes/lib, le second inclut le dossier de la bibliothèque dans le fichier JAR final et configure le fichier Manifest.mf.

Mais vous devrez ensuite ajouter du code de chargement de classe personnalisé pour charger les fichiers JAR.

Ou, pour éviter le chargement de classe personnalisé, vous pouvez utiliser "$ {project.build.directory}/lib, mais dans ce cas, vous n'avez pas de dépendances à l'intérieur du fichier JAR final, ce qui va à l'encontre de l'objectif recherché.

Cela fait deux ans que la question a été posée. Le problème des fichiers JAR imbriqués persiste néanmoins. J'espère que ça aide quelqu'un.

76
gmode

Mis à jour:

<build> 
  <plugins> 
    <plugin> 
    <artifactId>maven-dependency-plugin</artifactId> 
    <executions> 
      <execution> 
        <phase>install</phase> 
          <goals> 
            <goal>copy-dependencies</goal> 
          </goals> 
          <configuration> 
             <outputDirectory>${project.build.directory}/lib</outputDirectory> 
          </configuration> 
        </execution> 
      </executions> 
    </plugin> 
  </plugins> 
</build> 
27
Ahmet Karakaya

Le moyen le plus simple et le plus efficace consiste à utiliser un plugin uber comme celui-ci:

          <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <finalName>uber-${artifactId}-${version}</finalName>
            </configuration>
        </plugin>

Vous aurez dénormalisé le tout dans un fichier JAR.

23
Andrey Borisov

Le plugin maven de l'exécutable peut être utilisé exactement à cette fin: créer des applications autonomes Java contenant toutes les dépendances sous forme de fichiers JAR dans un dossier spécifique.

Ajoutez simplement ce qui suit à votre pom.xml dans la section <build><plugins> (veillez à remplacer la valeur de mainClass en conséquence):

<plugin>
    <groupId>de.ntcomputer</groupId>
    <artifactId>executable-packer-maven-plugin</artifactId>
    <version>1.0.1</version>
    <configuration>
        <mainClass>com.example.MyMainClass</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>pack-executable-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Le fichier JAR créé se trouve dans target/<YourProjectAndVersion>-pkg.jar après avoir exécuté mvn package. Toutes ses dépendances lors de la compilation et de l'exécution seront incluses dans le dossier lib/ du fichier JAR.

Disclaimer: Je suis l'auteur du plugin.

12
Cybran

Voici comment je le fais:

    <plugin>
            <artifactId>maven-Assembly-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <appendAssemblyId>false</appendAssemblyId>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>com.project.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

Et puis je viens de courir:

mvn Assembly:assembly
3
Eduardo Andrade

J'ai trouvé cette réponse à la question:

http://padcom13.blogspot.co.uk/2011/10/creating-standalone-applications-with.html

Vous obtenez non seulement les fichiers lib dépendants dans un dossier lib, vous obtenez également un directeur bin avec à la fois un exécutable Unix et DOS.

L’exécutable appelle finalement Java avec un argument -cp qui répertorie également toutes vos bibliothèques dépendantes.

L'ensemble se trouve dans un dossier appasembly à l'intérieur du dossier cible. Épique.

============= Oui, je sais que c'est un vieux fil de discussion, mais les résultats de recherche arrivent toujours en tête des résultats, alors j'ai pensé que cela pourrait aider quelqu'un comme moi.

2
user4815755

C'est clairement un problème de classpath. Prenez en considération que le classpath doit changer un peu lorsque vous exécutez votre programme en dehors de l'EDI. Cela est dû au fait que IDE charge les autres fichiers JAR par rapport au dossier racine de votre projet, alors que dans le cas du fichier JAR final, il s'agit généralement d'une erreur.

Ce que j'aime faire dans ces situations, c'est de construire le JAR manuellement. Cela me prend au plus 5 minutes et cela résout toujours le problème. Je ne vous suggère pas de faire cela. Trouver un moyen d'utiliser Maven, c'est son but.

1
Radu Murzea