Статьи

Java EE7 и проект Maven для новичков — часть 4 — определение модуля ear

Возобновление из предыдущих частей

Часть № 1
Часть 2
Часть № 3

Мы возобновляем для 4-й части, наш простой проект в настоящее время имеет

  • модуль web maven (война)
  • модуль ejb (ejb), содержащий наши сессионные компоненты без сохранения состояния (EJB 3.1)
  • и второй (ejb) модуль, содержащий наши бины сущности (JPA2)

но нам все еще не хватает того, чтобы упаковать их всех, архива, который будет иметь типear’ (он же Enterprise Archive) .

Определяя наш ушной maven модуль

Как вы можете видеть на изображении ниже, мы создаем папку emtpy с именем sample-ear под sample-parent. В этой папке должен быть файл pom.xml. Наш новый модуль должен быть правильно указан в разделе « modules » файла sample-parent \ pom.xml.

CapturFiles_3

Основная цель нашего модуля ear maven — «настроить» знаменитый maven-ear-plugin , который будет вызываться maven и собирается создать наше окончательное развертываемое приложение.

Нам нужно сделать две простые вещи: добавить конфигурацию для maven-ear-plugin и добавить наши « внутренние » зависимости приложения от модуля ear, чтобы он «знал», какие модули должны искать. Давайте посмотрим:

Внутри уха pom.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<build>
   <finalName>sampleapp</finalName>
    <plugins>
       <!--Ear plugin -creating the ear - watch out skinny WARS!-->
        <plugin>
           <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <configuration>
              <finalName>sampleapp</finalName>
                <defaultJavaBundleDir>lib/</defaultJavaBundleDir>
                <skinnyWars>true</skinnyWars>
                 <modules>
                      <webModule>
                         <groupId>gr.javapapo</groupId>
                         <artifactId>sample-web</artifactId>
                       </webModule>
                        <ejbModule>
                           <groupId>gr.javapapo</groupId>
                           <artifactId>sample-services</artifactId>
                       </ejbModule>
                 </modules>
            </configuration>
         </plugin>
     </plugins>
</build>

Это сборка, обратите внимание на следующие разделы:

  • Помните, как мы делали другие модули, мы определили некоторую базовую общую конфигурацию для нашего плагина в « родительском » pom. Вернитесь и посмотрите, что уже есть для вас.
  • Обратите внимание на defaultJavaBundleDir , где мы определяем, где все библиотеки (кроме модулей верхнего уровня, которые будут находиться у нас в ухе, обычно это вложенная папка в ухе, называемая «lib»).
  • Что такое модуль верхнего уровня? На самом деле, это баночка (и) и войны, которые будут упакованы в ухо, и считаются гражданами первого уровня, как вы можете видеть, мы определяем 2, сеть выборки и службы выборки.
  • Следите за свойством skinnyWars . Включив этот переключатель, мы применяем определенный шаблон для упаковки наших сторонних библиотек, на которые ссылается наш военный проект . Проще говоря, наши военные архивы НЕ собираются включать какие-либо внешние библиотеки, которые мы могли бы определить как зависимости в своей папке WEB-INF \ lib, вместо всех этих библиотек они будут упакованы в путь defaultJavaBundleDir на уровне уха.

Вышеуказанная конфигурация не будет работать, если мы не добавим раздел «зависимости» нашего наушника.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<!-- our in app dependencies-->
    <dependencies>
        <dependency>
            <groupId>gr.javapapo</groupId>
            <artifactId>sample-web</artifactId>
            <version>${project.version}</version>
            <type>war</type>
        </dependency>
  
        <dependency>
            <groupId>gr.javapapo</groupId>
            <artifactId>sample-services</artifactId>
            <version>${project.version}</version>
            <type>ejb</type>
        </dependency>
    </dependencies>

Обратите внимание на следующее:

  • элемент зависимости в этом pom нуждается в атрибуте type.

Один хороший вопрос, который у вас может возникнуть, — где находится модуль sample-domain (jar)?

Что ж, этот модуль не позиционируется как элемент верхнего уровня в нашем ухе, потому что мы собираемся добавить его в качестве зависимости от модуля sample-services . Таким образом, наши сервисы будут зависеть от модуля компонентов управления данными. (Звучит справедливо). Поэтому нам нужно обновить pom.xml нашего модуля sample-services.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
  <artifactId>sample-services</artifactId>
  <name>sample-services</name>  
   <description>EJB service layer</description>
        <packaging>ejb</packaging>
        <dependencies>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-api</artifactId>
           </dependency>
           <dependency>
             <groupId>gr.javapapo</groupId>
             <artifactId>sample-domain</artifactId>
             <version>${project.version}</version>
          </dependency>
        </dependencies>
</project>

Таким образом, sample-services.jar собирается «извлечь» вдоль sample-domain.jar. По умолчанию (помните, что Maven — это все о соглашениях), когда мы определяем модуль верхнего уровня для уха, как, например, сервисы-образцы, его зависимости автоматически связываются с библиотекой ear по умолчанию JavaJundBundleDir ! Поэтому, когда мы упаковываем наше ухо, мы ожидаем увидеть упакованный файл jar-домена.

Еще одна недостающая зависимость

После нашей первой зависимости между модулем services и модулем entity в приложении нам понадобится еще одна. Наш военный модуль (веб-слой) будет использовать некоторые из наших сервисов, но для того, чтобы это сделать, необходимо иметь зависимость от модуля «сервисы». Таким образом, нам нужен файл pom.xml в проекте sample-web, соответственно.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<packaging>war</packaging>
        <build>
         <finalName>${project.artifactId}</finalName>
        </build>
          <dependencies>
             <dependency>
                   <groupId>javax</groupId>
                    <artifactId>javaee-api</artifactId>
                     <scope>provided</scope>
             </dependency>
            <dependency>
              <groupId>gr.javapapo</groupId>
              <artifactId>sample-services</artifactId>
            <version>0.0.1-SNAPSHOT</version>
           </dependency>
        </dependencies>

Давайте упаковывать нашу войну.

Мы готовы, наши основные зависимости установлены, наше ухо настроено, нам просто нужно упаковать. Под уровнем родительской папки в командной строке нам нужно просто набрать:

мвн чистый пакет

Мы закончили, давайте проверим папку ‘target’ модуля sample-ear. Наше последнее ухо готово, maven также создает «ухо» в разобранном виде (расширено на изображении ниже). Обратите внимание на наши 2 элемента верхнего уровня ear и на то, как sample-domain.jar находится в папке lib нашего уха. Также обратите внимание, что некоторые базовые библиотеки, такие как javaee-api.jar, не включены в папку lib. Так как мы добавили предоставленные в пом. (см. окончательную версию XML).

CapturFiles_5

И еще одна вещь… тощие войны и файлы MANIFEST.MF

В конце концов, мы могли бы остановиться здесь, с нашим последним слухом все в порядке и будет работать, но при всей вышеописанной конфигурации, особенно с нашим предпочтением создавать тощие войны, нам нужно обратить внимание на небольшую деталь. Файлы МАНИФЕСТА — это специальные дескрипторы внутри jar и wars, которые используются серверами приложений для определения местоположения и загрузки «зависимых» jar класса в путь к классу внутри уха.

Наша небольшая проблема заключается в файле MANIFEST.MF файла sample-web.war. Если мы распакуем сгенерированный файл войны и откроем с помощью текстового редактора файл MANIFEST.MF, мы увидим что-то вроде этого.

1
2
3
4
5
6
7
Manifest-Version: 1.0
Built-By: papo
Build-Jdk: 1.7.0_45
Class-Path: lib/sample-services-0.0.1-SNAPSHOT.jar lib/sample-services-0.0
 .1-SNAPSHOT.jar lib/sample-domain-0.0.1-SNAPSHOT.jar
Created-By: Apache Maven 3.2.1
Archiver-Version: Plexus Archiver

Вы можете заметить ошибку? По умолчанию созданный файл MANIFEST.MF указывает неверный путь для одного из наших jj-файлов верхнего уровня (sample-services). Наш sample-services.jar находится не внутри \ lib внутри уха, а является элементом верхнего уровня. Итак, как мы собираемся создать правильный манифест?

В конце концов нам нужно немного настроить плагин Maven-War. Нам нужно переписать поведение по умолчанию, как указано в родительском pom, и указать правильную запись для этой конкретной зависимости. Если у вас есть более одного, вам нужно добавить все банки, которые являются элементами верхнего уровня в конфигурации (убедитесь, что вы делаете это правильно, используйте пробел между записями). Так что в примере войны войны нам нужно добавить некоторую конфигурацию (дополнительную) поверх примененной. Смотрите изображение ниже.

CapturFiles_6

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

Вот и все, наше ухо готово.

Резюме

Вы можете найти окончательную версию этого поста в этом теге Git. С этим постом мы заканчиваем первую серию постов, начиная с нуля, применяя базовые принципы maven и создавая некоторые базовые модули maven для корпоративного java-приложения. Не стесняйтесь повторно использовать этот пример и расширить его, чтобы удовлетворить ваши собственные потребности. Это далеко не полный список с точки зрения удовлетворения всех ваших потребностей, но это хороший пример того, как начать, думать и настраивать в Maven.

Я собираюсь расширить этот пример, добавив больше модулей и используя больше возможностей maven в будущих публикациях.

Ссылка: Проект Java EE7 и Maven для новичков — часть 4 — определение модуля ear от нашего партнера JCG Париса Апостолопулоса в блоге Papo .