Почему исполняемый файл jar, упакованный Spring Boot, не может зависеть от других проектов?

Spring Boot
Почему исполняемый файл jar, упакованный Spring Boot, не может зависеть от других проектов?

Два дня назад мне задали этот вопрос:

«Брат Сонг, почему jar, упакованный моим проектом Spring Boot, всегда сообщает об ошибке class not found после того, как на него полагаются другие проекты?»

У всех такой вопрос, ибо не понятно чем отличается исполняемый jar от обычного jar? Сегодня брат Сун поговорит с вами по этому вопросу.

еще один плагин

JAR-файл, упакованный по умолчанию в Spring Boot, называется исполняемым JAR-файлом. Этот JAR-файл отличается от обычных JAR-файлов.java -jar xxx.jarвыполнение команды, нормальноеjarВ основном зависит от других приложений,Spring BootсделалjarОн может выполняться, но от него не могут зависеть другие приложения.Даже если он принудительно зависит от него, классы внутри не могут быть получены. Но исполняемые jar-файлы не уникальны для Spring Boot, и сами Java-проекты могут быть упакованы в исполняемые jar-файлы.

У некоторых друзей могут возникнуть сомнения, так как реализация одинаковаmvn packageКоманда для упаковки проекта, почему проект Spring Boot упакован как исполняемый jar-файл, а обычный проект упакован как неисполняемый jar-файл?

Поэтому мы должны упомянуть конфигурацию плагина по умолчанию в проекте Spring Boot.spring-boot-maven-plugin, этот упакованный плагин имеет пять функций, что видно из команды плагина:

Пять функций:

  • build-info: Создайте файл информации о сборке проекта build-info.properties.
  • repackage: это цель по умолчанию, вmvn packageПосле выполнения эта команда снова упаковывается для создания исполняемого jar-файла, и в то же времяmvn packageСгенерированная банка переименовывается в*.origin
  • run: это можно использовать для запуска приложений Spring Boot.
  • НАЧАЛО: Этоmvn integration-testэтап, продолжениеSpring BootУправление жизненным циклом приложений
  • стоп: это вmvn integration-testэтап, продолжениеSpring BootУправление жизненным циклом приложений

Эта функция по умолчанию является функцией переупаковки.Чтобы использовать другие функции, разработчику необходимо настроить ее явно.

Бэйл

Роль функции переупаковки состоит в том, чтобы сделать немного больше при упаковке:

  1. во-первыхmvn packageКоманда Упаковать проект в одинjar,этоjarпросто обычныйjar, может зависеть от других проектов, но не может быть выполнен
  2. repackageкоманда, упакованная в первый шагjarУпакуйте его снова и сделайте исполняемым файломjar, введя первый шаг вjarпереименован в*.originalдокумент

Например:

Упакуйте любой проект Spring Boot и выполнитеmvn packageкоманду или непосредственно вIDEAсредний щелчокpackage,следующее :

После успешной упаковкиtargetФайлы внутри следующие:

Здесь два файла, первыйrestful-0.0.1-SNAPSHOT.jarПредставляет упакованный исполняемый файлjar,секундаrestful-0.0.1-SNAPSHOT.jar.originalОн был переименован в процессе упаковки.jar, который является неисполняемымjar, но может зависеть от других проектовjar. Распаковав два файла, мы можем увидеть разницу между ними.

Сравнение двух банок

исполняемыйjarПосле распаковки каталог выглядит следующим образом:

Как видите, в исполняемом jar-файле наш собственный код находится вBOOT-INF/classes/каталог, кроме того, естьMETA-INFкаталог, в котором находитсяMANIFEST.MFфайл, откройте файл, содержание выглядит следующим образом:

Manifest-Version: 1.0
Implementation-Title: restful
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: org.javaboy.restful.RestfulApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.6.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher

Как видите, здесь определяетсяStart-Class, который является исполняемымjarначальный класс,Spring-Boot-ClassesПредставляет расположение нашего собственного скомпилированного кода,Spring-Boot-Libэто означает, что проект зависит отjarпозиция.

Другими словами, если вы хотите запустить исполняемый файлjarДля пакетов помимо добавления связанных зависимостей также необходимо настроитьMETA-INF/MANIFEST.MFдокумент.

Это структура исполняемого jar-файла, а как насчет структуры неисполняемого jar-файла?

Сначала мы ставим суффикс по умолчанию.originalУдалите, затем переименуйте файл, переименование завершено и извлеките:

После распаковки видно, что он не исполняемыйjarКорневой каталог эквивалентен нашемуclasspath, после распаковки вы можете увидеть наш код напрямую, он также имеетMETA-INF/MANIFEST.MFфайл, но в нем не определены классы запуска и т. д.

Manifest-Version: 1.0
Implementation-Title: restful
Implementation-Version: 0.0.1-SNAPSHOT
Build-Jdk-Spec: 1.8
Created-By: Maven Archiver 3.4.0

Уведомление

это не может быть выполненоjarЗависимости проекта также не упакованы.

Отсюда мы видим, что дваjar, хотя обаjarpackage, но внутренняя структура совершенно другая, поэтому один может выполняться напрямую, а другой может зависеть от других проектов.

Упаковка двух банок сразу

Вообще говоря, Spring Boot упакован непосредственно в исполняемый файл.jarВсе, не рекомендуется использовать Spring Boot как обычныйjarЗависимость от других проектов. Если есть такая необходимость, рекомендуется выделить зависимую часть отдельно, чтобы сделать общийMavenпроект, а затем ссылайтесь на него в Spring BootMavenпроект.

Если вам нужно упаковать Spring Boot в общийjarТехнически возможно зависеть от других проектов, что даетspring-boot-maven-pluginДобавьте в плагин следующую конфигурацию:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <classifier>exec</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

настроенclassifierозначает исполняемый файлjarимя, после настройки, после выполнения плагинаrepackageкоманда, это не дастmvn packageсделалjarПереименовали, поэтому упакованная баночка выглядит следующим образом:

Первый jar представляет собой jar-файл, от которого могут зависеть другие проекты, а второй jar-файл представляет собой исполняемый jar-файл.

Что ж, давайте поговорим о проблеме jar в Spring Boot, если у вас есть какие-либо вопросы, пожалуйста, оставьте сообщение для обсуждения.

Обратите внимание на общедоступную учетную запись [Jiangnan A Little Rain], сосредоточьтесь на технологиях с полным стеком, таких как Spring Boot + микросервисы и разделение интерфейса и сервера, делитесь регулярными видеоуроками, отвечайте на Java после того, как уделите внимание, и получайте Сухие товары Java тщательно приготовлены Songge для вас!