Как добавить зависимость в Spring Boot Jar в другом проекте?
У меня есть приложение Spring Boot, и я создал Jar из этого. Следующее мое 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>
Я хочу использовать эту банку в моем другом приложении, поэтому добавил эту банку в мое приложение. Но когда я вызываю метод в этом банке, он бросает ClassNotFoundException
,
Как я могу исправить эту проблему? Как я могу добавить зависимость в JAR Spring Boot?
12 ответов
По умолчанию Spring Boot переупаковывает ваш JAR в исполняемый JAR, и делает это, помещая все ваши классы внутрь BOOT-INF/classes
и все зависимые библиотеки внутри BOOT-INF/lib
, Следствием создания этого толстого JAR-файла является то, что вы больше не можете использовать его в качестве зависимости для других проектов.
Из пользовательского переупаковки классификатора:
По умолчанию
repackage
цель заменит исходный артефакт переупакованным. Это нормальное поведение для модулей, представляющих приложение, но если ваш модуль используется как зависимость от другого модуля, вам необходимо предоставить классификатор для переупакованного.Причина в том, что классы приложений упакованы в
BOOT-INF/classes
так что зависимый модуль не может загрузить перепакованные классы jar.
Если вы хотите сохранить исходный главный артефакт, чтобы использовать его в качестве зависимости, вы можете добавить classifier
в 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>
При такой конфигурации плагин Spring Boot Maven создаст 2 JAR-файла: основной будет таким же, как обычный проект Maven, а второй будет иметь добавленный классификатор и будет исполняемым JAR-файлом.
Ответ Тунаки правильный, но не работает в 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>
Spring Boot 2.x
Если вы используете
spring-boot-starter-parent
,repackage
цель выполняется автоматически при выполнении с идентификаторомrepackage
, В этой настройке должна быть указана только конфигурация, как показано в следующем примере:
<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>
Для Spring Boot 2 @Tunaki ответ должен быть немного изменен согласно документации, если spring-boot-starter-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>
Бери не лишнего <id>repackage</id>
необходимо перезаписать на исполнение из spring-boot-starter-parent
,
если вы хотите использовать проект spring-boot в качестве зависимости и в то же время хотите запускать его как jar-файл с весенней загрузкой, используйте приведенную ниже конфигурацию. с помощью приведенной ниже конфигурации вы можете достичь двух целей.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build information</id>
<goals>
<goal>build-info</goal>
</goals>
</execution>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
Эта конфигурация создает две банки, как показано на скриншоте ниже:
Вы можете расширить свой проект с помощью 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>
После сборки вы получите 3 банки. Основной будет таким же, как обычный проект Maven, а второй будет иметь добавленный exec классификатор и будет исполняемым JAR. Третье имя jar будет добавлено с помощью jar-with-dependencies и будет содержать ваши классы с классами, добавленными в качестве зависимостей в ваше приложение весенней загрузки (spring-boot-starter-web, thymeleaf,...), так что в pom Приложение, в которое вы хотите добавить этот проект в качестве зависимости, вам не нужно будет добавлять зависимости из проекта весенней загрузки.
То, что сказал @Tunaki, было в основном правильным, но единственная недостающая часть, основанная на вашем первоначальном вопросе:
Это бросание ClassNotFoundException. Внешний jar, используемый в весенней загрузке, отсутствует.
Это связано с тем, что FatJAR, созданный из пакета maven, имеет зависимые библиотеки, указанные в определенном месте, которое работает для того, как Spring Boot выполняет приложение. Если вы просто добавляете JAR в путь к классам другого приложения, вам следует делать то, что сказал @Tunaki, а также включать зависимые файлы JAR в путь к классам. Лучший способ работать с этим - использовать плагин Maven Dependency Plugin, специально предназначенный для dependency:copy-dependencies
mojo для загрузки всех зависимостей в папку, которую вы можете указать в качестве пути к библиотеке при компиляции другого приложения.
Используйте приведенный ниже раздел сборки, он сделает три вещи:
- Создайте банку с пружинной загрузкой, используя spring-boot-maven-plugin
- Создайте обычный jar с вашими скомпилированными классами исходного кода, используя maven-assembly-plugin
- Установите обычный jar в папку m2 локально
Если вы хотите развернуть обычный jar-файл в удаленном хранилище, настройте плагин 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>
Поместите приведенный ниже контент в файл с именем "sources-jar-build.xml" в папку ресурсов:
<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>
Все существующие ответы сделаны исходя из предположения, что проект Spring Boot, от которого должен зависеть другой проект, является приложением, что достаточно справедливо, поскольку вопрос сформулирован так.
Но если базовый проект предназначен для использования только как библиотека , т. е. он не содержит (разумного) класса Main, очевидно, что исполняемый код вообще не нуждается в переупаковке.
Так что в этом случае имеет смысл полностью пропустить переупаковку следующим образом:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Используйте плагин ниже для весенней загрузки версии 2.*
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.1.RELEASE</version>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
Я использовал версию 2.2.5, и она работает. добавьте его в свой pom.xml
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.5.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Вы можете настроить свои проекты так, чтобы пакетная программа запуска работала с jar-файлом, который будет использоваться совместно с другим приложением.
Сказано по-другому, в соответствии с вашим первоначальным запросом:
Я хочу использовать эту банку в моем другом приложении, поэтому добавил эту банку в мое приложение.
Допустим, ваш фляга - это ваш проект А, а ваше приложение - ваш проект Б.
Теперь я предлагаю удалить часть запуска из A; затем вы помещаете его в новый проект C, который будет включать Spring Boot, и который будет почти полностью полагаться на A.
Тогда, поскольку A теперь является простым jar, B может использовать его как зависимость.
Любой проект, если вы хотите добавить в качестве зависимости вам нужен этот проект <groupId>
,<artifactId>
,<version>
, с этими деталями вы можете добавить свой проект в качестве зависимости в другой модуль или приложение для ex: детали вашего приложения pom
<project
<groupId>com.sample</groupId>
<artifactId>sampleapp</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
</project>`
ваша зависимость, как показано ниже
<dependency>
<groupId>com.sample</groupId>
<artifactId>sampleapp</artifactId>
<version>1.0</version>
</dependency>