web-dev-qa-db-fra.com

Comment ajouter une dépendance à un Spring Boot Jar dans un autre projet?

J'ai une application Spring Boot et j'ai créé un Jar à partir de ça. Voici mon pom.xml:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-Java8time</artifactId>
        <version>2.1.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- WebJars -->
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.6.2</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Je veux utiliser ce bocal dans mon autre application, alors j'ai ajouté ce bocal à mon application. Mais quand j'appelle une méthode dans ce Jar, il lance un ClassNotFoundException.

Comment puis-je résoudre ce problème? Comment ajouter une dépendance à un fichier JAR de démarrage Spring?

44
sparrow

Par défaut, Spring Boot reconditionne votre fichier JAR en un fichier JAR exécutable. Pour ce faire, il place toutes vos classes dans BOOT-INF/classes, et toutes les bibliothèques dépendantes à l'intérieur de BOOT-INF/lib. La conséquence de la création de ce gros fichier JAR est que vous ne pouvez plus l'utiliser comme dépendance pour d'autres projets.

De classificateur de reconditionnement personnalisé :

Par défaut, l'objectif repackage remplacera l'artefact d'origine par celui reconditionné. C'est un comportement sain pour les modules qui représentent une application, mais si votre module est utilisé comme dépendance d'un autre module, vous devez fournir un classificateur pour celui qui est reconditionné.

La raison en est que les classes d’application sont packagées dans BOOT-INF/classes afin que le module dépendant ne puisse pas charger les classes d'un fichier jar reconditionné.

Si vous souhaitez conserver l'artefact principal d'origine afin de l'utiliser comme dépendance, vous pouvez ajouter un classifier dans la configuration de l'objectif repackage:

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <version>1.4.1.RELEASE</version>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
      <configuration>
        <classifier>exec</classifier>
      </configuration>
    </execution>
  </executions>
</plugin>

Avec cette configuration, le plug-in Spring Boot Maven créera 2 JAR: le principal sera identique à un projet Maven habituel, tandis que le second aura le classifieur ajouté et sera le JAR exécutable.

92
Tunaki

Ce que @Tunaki a déclaré était en grande partie correct, mais la partie manquante sur la base de votre question initiale était:

Cette levée ClassNotFoundException. Le pot externe utilisé dans l'application de démarrage de printemps est manquant.

Cela est dû au fait que le FatJAR créé à partir du package maven contient les bibliothèques dépendantes spécifiées à un emplacement spécifique qui fonctionne pour l'exécution de l'application par Spring Boot. Si vous ajoutez simplement le fichier JAR à un chemin d'accès aux classes d'une autre application, vous devez faire ce que @Tunaki a dit et inclure également les fichiers JAR dépendants dans le chemin d'accès aux classes. La meilleure façon de travailler avec cela est d'utiliser le plugin Maven Dependency , ciblant spécifiquement le dependency:copy-dependencies mojo pour télécharger toutes les dépendances dans un dossier que vous pouvez ensuite spécifier en tant que chemin de la bibliothèque lors de la compilation de l’autre application.

2
Shawn Clark

La réponse de Tunaki est correcte mais ne fonctionne pas dans Spring Boot 2 .

Spring Boot 1.x

  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.5.20.RELEASE</version>
    <executions>
      <execution>
        <goals>
          <goal>repackage</goal>
        </goals>
        <configuration>
          <classifier>exec</classifier>
        </configuration>
      </execution>
    </executions>
    ...
  </plugin>

en savoir plus


Spring Boot 2.x

Si vous utilisez spring-boot-starter-parent, l’objectif repackage s’exécute automatiquement lors d’une exécution portant l’ID repackage. Dans cette configuration, seule la configuration doit être spécifiée comme indiqué dans l'exemple suivant:

  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
      <execution>
        <id>repackage</id>
        <configuration>
          <classifier>exec</classifier>
        </configuration>
      </execution>
    </executions>
    ...
  </plugin>

en savoir plus

2
Andrea Ligios

Vous pouvez prolonger votre projet avec maven-Assembly-plugin

<plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-Assembly-plugin</artifactId>
        <version>3.1.0</version>
        <configuration>
        <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>

Après la construction, vous obtiendrez 3 pots. Le principal sera le même qu’un projet Maven habituel, tandis que le second aura le classifieur ajouté avec exec et sera le fichier JAR exécutable. Le troisième nom de jar sera ajouté par jar-with-dependencies et contiendra vos classes avec des classes ajoutées comme dépendances dans votre application de démarrage printanière (spring-boot-starter-web, thymeleaf, ...), donc dans le pom du Si vous souhaitez ajouter ce projet en tant que dépendance, vous n’aurez pas à ajouter de dépendances à partir du projet Spring Boot.

2
Gabriel Mohňanský

Pour Spring Boot 2 @Tunaki, la réponse doit être légèrement modifiée conformément à la documentation si spring-boot-starter-parent Est utilisé comme parent:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
      <execution>
        <id>repackage</id>
        <configuration>
          <classifier>exec</classifier>
        </configuration>
      </execution>
    </executions>

Ne prenez pas le supplément <id>repackage</id> Nécessaire pour écraser l'exécution à partir du spring-boot-starter-parent.

0
k_o_

Vous pouvez configurer vos projets pour que le programme de lancement par lots repose sur un fichier jar, qui serait partagé avec votre autre application.

Dit différemment, selon votre demande initiale:

Je veux utiliser ce bocal dans mon autre application, alors j'ai ajouté ce bocal à mon application.

Supposons que votre pot correspond à votre projet A et votre application à votre projet B.

Maintenant, ce que je suggère, est que vous retiriez la partie lancement de A; ensuite, vous le mettez dans un nouveau projet C, qui intégrerait Spring Boot, et qui reposerait presque totalement sur A.

Puis, puisque A est maintenant un simple pot, B peut l’utiliser comme dépendance.

0
dounyy

Utilisez la section de construction fournie ci-dessous, cela fera trois choses:

  1. Créez le pot de démarrage à ressort à l'aide de spring-boot-maven-plugin
  2. Créez un fichier jar normal avec vos classes compilées avec le code source en utilisant maven-Assembly-plugin
  3. Installer le fichier jar normal dans le dossier m2 localement
  4. Si vous souhaitez déployer le fichier jar normal dans un référentiel distant, configurez le plugin deploy

    <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">
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-Assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <appendAssemblyId>true</appendAssemblyId>
                            <descriptors>
                                <descriptor>src/main/resources/sources-jar-build.xml</descriptor>
                            </descriptors>
                            <finalName>${pom.artifactId}-${pom.version}</finalName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                 <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <executions>
                    <execution>
                        <id>install-file</id>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>
                            <file>${pom.artifactId}-${pom.version}</file>
                            <artifactId>${pom.artifactId}</artifactId>
                            <groupId>${pom.groupId}</groupId>
                            <version>${pom.version}</version>
                        </configuration>
                    </execution>
                </executions>               
            </plugin>
        </plugins>
    </build>
    

Placez le contenu ci-dessous dans un fichier nommé "sources-jar-build.xml", dans le dossier des ressources:

<Assembly
    xmlns="http://maven.Apache.org/plugins/maven-Assembly-plugin/Assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.Apache.org/plugins/maven-Assembly-plugin/Assembly/1.1.2 http://maven.Apache.org/xsd/Assembly-1.1.2.xsd">
    <id>sources</id>
    <includeBaseDirectory>false</includeBaseDirectory>

    <formats>
        <format>jar</format>
    </formats>
    <fileSets>
        <fileSet>
            <directory>${project.basedir}/target/classes</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
    </fileSets>
</Assembly>
0
Kumar Abhishek