1. Обзор
Apache Maven-это широко используемый инструмент управления зависимостями проектов и инструмент построения проектов.
За последние несколько лет Spring Boot стал довольно популярным фреймворком для создания приложений. Существует также плагин Spring Boot Maven , обеспечивающий поддержку Spring Boot в Apache Maven.
Мы знаем, что когда мы хотим упаковать наше приложение в JAR или WAR артефакт с помощью Maven, мы можем использовать mvn пакет . Однако плагин Spring Boot Maven поставляется с целью repackage , и он также вызывается в команде mvn .
Иногда две команды mvn сбивают с толку. В этом уроке мы обсудим разницу между mvn package и spring-boot:repackage .
2. Пример Приложения Spring Boot
Прежде всего, мы создадим простое приложение Spring Boot в качестве примера:
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
Чтобы проверить, работает ли ваше приложение, давайте создадим простую конечную точку REST:
@RestController public class DemoRestController { @GetMapping(value = "/welcome") public ResponseEntity welcomeEndpoint() { return ResponseEntity.ok("Welcome to Baeldung Spring Boot Demo!"); } }
3. Цель пакета Maven
Нам нужна только зависимость spring-boot-starter-web для создания нашего приложения Spring Boot:
spring-boot-artifacts-2 jar ...... org.springframework.boot spring-boot-starter-web
Maven package goal возьмет скомпилированный код и упакует его в распространяемый формат , который в данном случае является форматом JAR:
$ mvn package [INFO] Scanning for projects... [INFO] ------< com.baeldung.spring-boot-modules:spring-boot-artifacts-2 >------ [INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-artifacts-2 --- [INFO] Building jar: /home/kent ... /target/spring-boot-artifacts-2.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ ...
После выполнения команды mvn package мы можем найти встроенный файл JAR spring-boot-artifacts-2.jar в каталоге target . Давайте проверим содержимое созданного файла JAR :
$ jar tf target/spring-boot-artifacts-2.jar META-INF/ META-INF/MANIFEST.MF com/ com/baeldung/ com/baeldung/demo/ application.yml com/baeldung/demo/DemoApplication.class com/baeldung/demo/DemoRestController.class META-INF/maven/...
Как мы можем видеть в выводе выше, файл JAR, созданный командой mvn package , содержит только ресурсы и скомпилированные классы Java из исходного кода нашего проекта .
Мы можем использовать этот файл JAR в качестве зависимости в другом проекте. Однако мы не можем выполнить файл JAR с помощью java-jar JAR_FILE , даже если это приложение для загрузки Spring. Это связано с тем, что зависимости времени выполнения не ограничены. Например, у нас нет контейнера сервлетов для запуска веб-контекста.
Чтобы запустить наше приложение Spring Boot с помощью простой команды java-jar , нам нужно создать fat JAR . Плагин Spring Boot Maven может помочь нам в этом.
4. Цель переупаковки Плагина Spring Boot Maven
Теперь давайте выясним, что делает spring-boot:repackage .
4.1. Добавление плагина Spring Boot Maven
Чтобы выполнить цель repackage , нам нужно добавить плагин Spring Boot Maven в ваш pom.xml :
${project.artifactId} org.springframework.boot spring-boot-maven-plugin
4.2. Выполнение задачи spring-boot:переупаковка
Теперь давайте очистим ранее созданный файл JAR и попробуем spring-boot:repackage :
$ mvn clean spring-boot:repackage ... [INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) @ spring-boot-artifacts-2 --- [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ ... [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) on project spring-boot-artifacts-2: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:repackage failed: Source file must not be null -> [Help 1] ...
Упс, это не работает. Это связано с тем, что цель spring-boot:repackage принимает существующий архив JAR или WAR в качестве источника и переупаковывает все зависимости времени выполнения проекта внутри конечного артефакта вместе с классами проекта. Таким образом, переупакованный артефакт выполняется с помощью командной строки java-jar JAR_FILE.jar .
Поэтому нам нужно сначала создать файл JAR перед выполнением цели spring-boot:repackage :
$ mvn clean package spring-boot:repackage ... [INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-artifacts-2 --- [INFO] Building jar: /home/kent/.../target/spring-boot-artifacts-2.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) @ spring-boot-artifacts-2 --- [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS ...
4.3. Содержимое переупакованного файла JAR
Теперь, если мы проверим каталог target , мы увидим переупакованный файл JAR и исходный файл JAR:
$ ls -1 target/*jar* target/spring-boot-artifacts-2.jar target/spring-boot-artifacts-2.jar.original
Давайте проверим содержимое переупакованного файла JAR:
$ jar tf target/spring-boot-artifacts-2.jar META-INF/ META-INF/MANIFEST.MF ... org/springframework/boot/loader/JarLauncher.class ... BOOT-INF/classes/com/baeldung/demo/ BOOT-INF/classes/application.yml BOOT-INF/classes/com/baeldung/demo/DemoApplication.class BOOT-INF/classes/com/baeldung/demo/DemoRestController.class META-INF/maven/com.baeldung.spring-boot-modules/spring-boot-artifacts-2/pom.xml META-INF/maven/com.baeldung.spring-boot-modules/spring-boot-artifacts-2/pom.properties BOOT-INF/lib/ BOOT-INF/lib/spring-boot-starter-web-2.3.3.RELEASE.jar ... BOOT-INF/lib/spring-boot-starter-tomcat-2.3.3.RELEASE.jar BOOT-INF/lib/tomcat-embed-core-9.0.37.jar BOOT-INF/lib/jakarta.el-3.0.3.jar BOOT-INF/lib/tomcat-embed-websocket-9.0.37.jar BOOT-INF/lib/spring-web-5.2.8.RELEASE.jar ... BOOT-INF/lib/httpclient-4.5.12.jar ...
Если мы проверим вывод выше, он будет намного длиннее, чем файл JAR, созданный командой mvn package .
Здесь, в переупакованном файле JAR, у нас есть не только скомпилированные классы Java из нашего проекта, но и все библиотеки времени выполнения, необходимые для запуска нашего приложения Spring Boot . Например, встроенная библиотека tomcat упакована в каталог BOOT-INF/lib .
Далее, давайте запустим наше приложение и проверим, работает ли оно:
$ java -jar target/spring-boot-artifacts-2.jar . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ 2020-12-22 23:36:32.704 INFO 115154 [main] com.baeldung.demo.DemoApplication : Starting DemoApplication on YK-Arch with PID 11515... ... 2020-12-22 23:36:34.070 INFO 115154 [main] o.s.b.w.embedded.tomcat.TomcatWebServer: Tomcat started on port(s): 8080 (http) ... 2020-12-22 23:36:34.078 INFO 115154 [main] com.baeldung.demo.DemoApplication : Started DemoApplication in 1.766 seconds ...
Наше приложение Spring Boot запущено и запущено. Теперь давайте проверим это, позвонив в нашу конечную точку /welcome :
$ curl http://localhost:8080/welcome Welcome to Baeldung Spring Boot Demo!
Отлично! Мы получили ожидаемый ответ. Наше приложение работает правильно.
4.4. Выполнение spring-boot:цель переупаковки В Течение Жизненного Цикла пакета Maven
Мы можем настроить плагин Spring Boot Maven в вашем pom.xml для переупаковки артефакта во время фазы package жизненного цикла Maven. Другими словами, когда мы выполняем пакет mvn, | spring-boot:repackage будет автоматически выполнен.
Конфигурация довольно проста. Мы просто добавляем цель repackage в элемент execution :
${project.artifactId} org.springframework.boot spring-boot-maven-plugin repackage
Теперь давайте еще раз запустим mvn clean package :
$ mvn clean package ... [INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- ... [INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default) @ spring-boot-artifacts-2 --- [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS ...
Вывод показывает, что цель переупаковки была выполнена. Если мы проверим файловую систему, то обнаружим, что переупакованный файл JAR создан:
$ ls -lh target/*jar* -rw-r--r-- 1 kent kent 29M Dec 22 23:56 target/spring-boot-artifacts-2.jar -rw-r--r-- 1 kent kent 3.6K Dec 22 23:56 target/spring-boot-artifacts-2.jar.original
5. Заключение
В этой статье мы обсудили разницу между пакетом mvn и spring-boot:repackage .
Кроме того, мы узнали, как выполнить spring-boot:repackage во время фазы package жизненного цикла Maven.
Как всегда, код в этой записи полностью доступен на GitHub .