Статьи

Миграция в Maven 2 (часть 2)

Maven 2 обладает фантастическими возможностями многократной сборки проекта. Мы исследуем эту особенность, предоставив другие материалы Jar от Mavenizing Guice. В этой части учебника мы будем использовать плагин Mavenize Guice Spring Bridge, Servlet инжектор и Struts 2, а также пример Mavenize Struts 2 в части 3.

Если вы начинаете этот урок с части 2, вам нужно вернуться назад. в части 1 руководства и загрузите исходный код Guice, установите cglib-nodep-2.2_beta-1 и поместите файл pom.xml, указанный в конце части 1, в корень исходного каталога Guice. Предполагая, что вы сделали все это (или вы закончили первую часть), вы готовы приступить ко второй части руководства.

Быстрый тур по многомодульным сборкам Maven

Maven 2 имеет возможность создавать несколько связанных (под) проектов в одном цикле сборки, что позволяет нескольким группам совместно использовать один и тот же цикл сборки и зависимости и легко определять, проходит ли сборка в целом или нет. Файлы Pom.xml на самом деле проще для больших сборок, потому что в каждом файле POM должны быть указаны только зависимости, но не номера версий. Номера версий для зависимостей, а также вся другая информация о проекте перечислены в так называемом «родительском POM» в разделе <dependencyManagement>, и их не нужно повторять в других POM. Эта функция позволяет легко добавлять как новые модули проекта, так и обновлять зависимости. Родительский проект pom и имеет <package> pom </ packaging> вместо <packaging> jar </ packaging>,сделать его довольно легко обнаружить.

Хотя родительский pom-файл может находиться в любом месте проекта, он обычно находится в корне исходного каталога проекта. Каждый подпроект, известный как модуль, обычно является родственным файлом родительского файла pom.xml. Каждый из этих каталогов указан в разделе <modules> родительского POM, поэтому Maven 2 знает, как его искать, и файл POM каждого модуля часто называют «дочерним POM».

Вся сборка проекта может быть запущена из каталога, в котором находится родительский POM, собирая все модули, перечисленные в разделе <modules> родительского pom. В качестве альтернативы, отдельный модуль может быть собран путем запуска Maven в каталоге этого модуля. Вся информация о проекте унаследована от родительского pom, но для использования зависимости в модуле она должна быть указана в разделе <modules>. Если один модуль проекта используется в качестве зависимости в другом, те же самые зависимости не нужно повторно перечислять, поскольку они являются переходными. Области зависимости могут быть перечислены в родительском или дочернем POM, в зависимости от того, применима ли область действия для всего проекта (например, JUnit) или для каждого модуля (например, Spring, который мы увидим позже)

Родительские POM и дочерние POM-отношения очень хорошо описаны в статье Эрика Редмонда « Демифицированный POM Maven 2» , первая часть главы 3 « Лучшая сборка с Maven» , а также в главе 6 и главе 7 « Maven: полное руководство»

. POM родителей и ребенок POM вместе составляют то, что известно как «эффективное POM». Эффективное POM модуля можно просмотреть в любое время, запустив

> mvn help :ffective-pom

 

Создание Guice Модульный

Наша цель — сделать то же самое, что делает Guice со своими текущими скриптами сборки Ant. Чтобы создать файлы Jar, которые мы пытаемся тиражировать, перейдите в каталог guice-1.0-src и запустите

> муравейник

Банки будут помещены в каталог guice-1.0-src / build / dist.

Модуль Guice

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

  1. Создайте каталог в вашем каталоге guice-1.0-src под названием guice
  2. Скопируйте каталоги guice-1.0-src / src и guice-1.0-src / test в только что созданный каталог guice

Теперь создайте файл pom.xml в каталоге guice и используйте для него следующий XML:

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.google.code.guice</groupId>
<artifactId>guice-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>guice</artifactId>
<name>guice</name>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>

Вы заметите, что номера версий не указаны ни в одной из зависимостей. Если вы хотите сделать версию jar «липкой» для дочернего POM, даже если версия может быть изменена в родительском файле, вы можете объявить номер версии. Однако практика не рекомендуется. Вы также заметите, что мы добавили раздел <parent>, в котором указано, какой POM следует использовать в качестве родительского POM.

Теперь нам нужно обновить POM из части 1 (в каталоге guice-1.0-src), чтобы превратить его в родительский POM.

  1. Измените <Packaging> Jar </ Packaging> на <Packaging> POM </ Packaging> в верхней части
  2. Измените <artifactId> guice </ artifactId> на <artifactId> guice-parent </ artifactId> вверху
  3. Добавьте раздел <modules> чуть ниже раздела <build> (он не будет работать, если вы поместите его перед разделом <build>, хотя я не уверен, почему)
      <modules>
    <module>guice</module>
    </modules>
  4. Поместите элемент <dependencyManagement> и соответствующий элемент </ dependencyManagement> вокруг раздела <dependencies>. Это говорит Maven, что вы будете использовать эти зависимости в своих дочерних POM

Обратите внимание, что имя модуля совпадает с именем каталога, в котором находится код для этого модуля, и именно так Maven находит модули проекта, которые должны быть собраны как часть цикла сборки. Дочерние модули не обязательно должны быть перечислены, но они все равно могут использовать определения родительского POM. Мы увидим этот тип ситуации в третьей части.

После добавления дочернего POM в каталог guice и обновления родительского POM в каталоге guice-1.0-src выполните команду

> mvn compile

в каталоге guice-1.0-src, и вы должны увидеть BUILD SUCCESSFUL

Если вы создадите сайт, вы найдете статическую документацию по проекту, расположенную в каталоге guice-1.0-src / target / site, а отчет приведет к появлению каталога guice-1.0-src / guice / target / site. Это известная проблема — было бы разумно, чтобы все веб-сайты модулей были доступны с родительского веб-сайта, — но, к сожалению, с этим нужно бороться до тех пор, пока он не будет исправлен.

 

Модуль «Весенний мост»

  1. Добавьте <module> spring </ module> в раздел <modules> вашего родительского POM
  2. Удалите <scope> test </ scope> из зависимостей spring-core и spring-bean в родительском POM, поскольку они теперь используются в качестве зависимостей артефактов Guice.
  3. Добавьте свойство версии — это будет полезно, когда нам нужно обновить артефакты:
    <properties>
    <guiceVersion>1.0</guiceVersion>
    </properties>
  4. Поскольку для модуля Spring Bridge требуется основной модуль Guice, нам необходимо добавить его в раздел <dependencyManagement>. Добавьте следующий XML родительский POM в разделе <dependencies>:
          <dependency>
    <groupId>com.google.code.guice</groupId>
    <artifactId>guice</artifactId>
    <version>${guiceVersion}</version>
    </dependency>
  5. Создайте файл pom.xml в каталоге guice-1.0-src / spring со следующим содержимым:
    <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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>com.google.code.guice</groupId>
    <artifactId>guice-parent</artifactId>
    <version>1.0</version>
    </parent>
    <artifactId>guice-spring</artifactId>
    <name>guice-spring</name>
    <packaging>jar</packaging>

    <dependencies>
    <dependency>
    <groupId>com.google.code.guice</groupId>
    <artifactId>guice</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>

    </project>

 

Если ваша сборка на данный момент не компилируется, в родительском POM может присутствовать объявление <scope> test </ scope> для зависимостей spring-core и spring-beans. Как только вы удалите их, он должен скомпилироваться просто отлично.

Однако, пытаясь запустить тесты, мы обнаруживаем, что тестовый класс SpringIntegration не компилируется, что указывает на отсутствие пакета импорта com.google.inject.PerformanceComparison. Рассматривая его, Maven рассматривает родительский класс статического внутреннего класса TeeImpl как пакет в операторе импорта. Делая быстрый поиск в Google , похоже, что это не первый раз, когда возникает эта проблема, но не ясно, была ли она введена в JIRA. Я нашел похожую проблему Surefire SUREFIRE-44Но я не думаю, что это одно и то же. К счастью, импорт не используется в классе SpringIntegrationTest, куда он импортируется, поэтому сейчас мы удалим импорт; В действительности же, это может быть реальным шоу-стопом, и почти в нашем случае. После удаления строки импорта com.google.inject.PerformanceComparison.TeeImpl; из класса SpringIntegrationTest.java модульные тесты работают нормально, и мы вернулись на правильный путь.

 

Модуль сервлетов

  1. Добавьте <module> servlet </ module> в раздел <modules> вашего родительского POM
  2. Добавьте следующие зависимости в родительский POM в разделе <dependencies>:
          <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    </dependency>
    <dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>2.2</version>
    <scope>test</scope>
    </dependency>
  3. Создайте файл pom.xml в каталоге guice-1.0-src / servlet со следующим содержимым:
    <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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>com.google.code.guice</groupId>
    <artifactId>guice-parent</artifactId>
    <version>1.0</version>
    </parent>
    <artifactId>guice-servlet</artifactId>
    <name>guice-servlet</name>
    <packaging>jar</packaging>

    <dependencies>
    <dependency>
    <groupId>com.google.code.guice</groupId>
    <artifactId>guice</artifactId>
    </dependency>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>

    </project>

К счастью, все юнит-тесты прошли без проблем, и мы можем уверенно перейти на плагин Guice Struts 2.

 

Плагин Guice Struts 2

  1. Добавьте <module> struts2 / plugin </ module> в раздел <modules> родительского POM, поскольку плагин struts2 находится в этом каталоге относительно каталога guice-1.0-src.
  2. Добавьте следующие зависимости к родительскому POM в разделе <dependencies>. Обратите внимание, что, хотя для использования Struts2 в папке struts2 / lib требуется множество плагинов, нам нужно только указать зависимость struts2-core
          <dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.0.5</version>
    </dependency>
    <dependency>
    <groupId>com.google.code.guice</groupId>
    <artifactId>servlet</artifactId>
    <version>1.0</version>
    </dependency>
  3. Создайте файл pom.xml в каталоге guice-1.0-src / struts2 / plugin со следующим содержимым:
    <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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>com.google.code.guice</groupId>
    <artifactId>guice-parent</artifactId>
    <version>1.0</version>
    <relativePath>../..</relativePath>
    </parent>
    <artifactId>guice-struts2-plugin</artifactId>
    <name>guice-struts2-plugin</name>
    <packaging>jar</packaging>

    <build>
    <resources>
    <resource>
    <directory>src</directory>
    <excludes>
    <exclude>**/*.java</exclude>
    </excludes>
    </resource>
    </resources>
    </build>

    <dependencies>
    <dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    </dependency>
    <dependency>
    <groupId>com.google.code.guice</groupId>
    <artifactId>guice-servlet</artifactId>
    </dependency>
    </dependencies>

    </project>
  4. Команда Guice выпустила версию 1.0.1 плагина Struts2 после первоначального выпуска Guice, и вы можете по желанию обновить исходный файл GuiceObjectFactory в модуле, чтобы отразить это изменение. Обновленный источник для GuiceObjectFactory можно найти здесь . Хотя это и не нужно для целей этого учебного цикла, я бы порекомендовал это изменение, если вы собираете плагин в своей команде разработчиков.

Вы, наверное, заметили, как мы добавили элемент <lativePath> ../ .. </lativePath> в родительское объявление. Это не нужно объявлять, если родительский POM находится в родительском каталоге прямо над модулем, но делает, если родительский POM находится в другом месте проекта. В нашем случае родительский POM находится в двух каталогах, но мог находиться в совершенно другом месте.

Мы также создали объявление <resources> в разделе <build>. Это позволяет добавить файл struts-plugin.xml в jar при его упаковке. Мы также добавили раздел <exclude>, который исключает все файлы * .java в проекте, чтобы предотвратить их добавление. Несмотря на то, что мы добавили раздел <build>, нам не нужно было повторно объявлять исходную версию или каталоги сборки и тестирования.

 

Собираем все вместе

Команды Maven 2 могут быть выполнены из корневого исходного каталога (guice-1.0-src) для компиляции, тестирования и упаковки, или команды могут быть запущены в каждом из каталогов проекта, таких как guice-1.0-src / guice, guice-1.0-src / spring и т. д. Однако каждый из модулей, от которого зависит данный модуль, должен быть установлен в вашем локальном хранилище. Например, если мы хотим работать с кодом плагина Struts 2, модуль guice и модуль guice-servlet должны быть установлены с помощью команды

> установить mvn

Если вы запустите команду

> мвн пакет

из каталога guice-1.0-src вы найдете файл Jar в целевом каталоге каждого из модулей, который идентичен Jars в каталоге guice-1.0-src / build / dist, file-to-file и почти побайтово (хорошо — за исключением основной карты Jar, но это потому, что зависимости не перепаковываются в Jar). Все банки можно опубликовать в вашем любимом хранилище, запустив

> Mvn развертывания

команда. В этот момент ваши товарищи по команде теперь могут использовать только что созданные банки.

 

Вывод

Мы перенесли проект Guice с генерации одного артефакта Jar на создание нескольких артефактов Jar, которые можно сгенерировать и совместно использовать с помощью одной команды. Нам пришлось проделать небольшую работу, чтобы заставить Maven работать с исходным кодом Guice, но исходный код не подвергался какой-либо серьезной реорганизации или реструктуризации.

В третьей и последней части руководства мы рассмотрим, как использовать и использовать плагин Maven для Jetty.

 

Ресурсы