Многомодуль Maven: ошибка при сборке WAR: требуется атрибут webxml

Я превращаю один проект веб-приложения, управляемый Eclipse Maven, в многомодульный проект Maven (это тестовый проект для экспериментов с Maven, поэтому не стесняйтесь вносить любые предложения).

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

Приложение имеет веб-часть и консольную часть, а это означает, что есть некоторые классы с методом main(), которые при запуске из Eclipse (с запуском от имени -> приложение Java) работают должным образом. Обе части показывают данные из базы данных, запрашиваемые либо напрямую через JDBC, либо через jOOQ.

Итак, вот как я разделил проект:

  • ядро (содержит все общее с двумя другими частями);
  • runnable (содержит классы, имеющие метод main());
  • webapp (часть веб-приложения).

Внутри Eclipse у меня сейчас 4 отдельных проекта:

  • shaker-multi содержит агрегатор (и родительский) POM, а также каждый модуль в подкаталоге;
  • shaker-multi-core;
  • shaker-multi-runnable;
  • shaker-multi-webapp.

Внутри Eclipse компилируются core и webapp, и последнее можно развернуть на экземпляре Tomcat, и я вижу его в браузере.

Проблема возникает с runnable. Этот проект основан на классах jOOQ, поэтому необходимо сгенерировать соответствующий исходный код. Зависимости и конфигурация jOOQ находятся в core/pom.xml (поскольку они могут использоваться и там).

Когда я делаю Project -> Run As -> Maven build... -> clean generate-sources, на shaker-multi-core я получаю:

Non-resolvable parent POM: Failure to find sunshine.web:shaker-multi:pom:0.0.1

что звучит разумно, поскольку я не устанавливал ни одного из этих артефактов даже в своем локальном репозитории.

Но когда я вызываю Maven build... -> 'чистая установка' на shaker-multi, он ломается, потому что не может найти файл web.xml для shaker-multi-webapp (хотя он правильно находится в shaker-multi-webapp/src/main/webapp/WEB-INF/web.xml).

Что я должен делать? Является ли конфигурация/разделение моего проекта совершенно неправильной? Должен ли я добавить еще один модуль с родительским POM? Это звучит неправильно, поскольку в справочнике POM указано:

Наследование и агрегация создают удобную динамику для управления сборками через единую высокоуровневую POM. Вы часто будете видеть проекты, которые одновременно являются и родительскими, и агрегаторами.

Я совсем потерялся здесь.

Мои ожидания:

  • запустить Maven package на shaker-multi-webapp и получить развертываемую войну;
  • запустите Maven package на shaker-multi-runnable и получите запускаемый из командной строки jar (мне все еще нужно настроить его POM для создания jar-с-зависимостями, хотя, я знаю);
  • запустить Maven package на shaker-multi и получить какой-то комплект, который я могу перемещать и который будет содержать war или jar каждого модуля.

ИЗМЕНИТЬ

я добавил

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
            <webXml>src/main/webapp/WEB-INF/web.xml</webXml>        
            </configuration>
        </plugin>

на shaker-multi-webapp POM, как показано в этом ответе, но без разницы.


EDIT-2

Я очистил весь свой локальный репозиторий (как было предложено здесь), и когда я снова открыл Eclipse, в консоли Maven я увидел

[...]
05/09/14 07:58:19 CEST: [INFO] Adding source folder /shaker-multi-webapp/src/main/java
05/09/14 07:58:19 CEST: [INFO] Adding source folder /shaker-multi-webapp/src/test/java
**05/09/14 07:58:19 CEST: [ERROR] Could not read web.xml**
[...]

Любой намек? Откуда оно взялось? Однако я не могу воспроизвести его (без повторного удаления всего моего локального репо).


Это shaker-multi ПОМ:

<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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>sunshine.web</groupId>
    <artifactId>shaker-multi</artifactId>
    <version>0.0.1</version>
    <packaging>pom</packaging>

    <modules>
        <module>shaker-multi-core</module>
        <module>shaker-multi-runnable</module>
        <module>shaker-multi-webapp</module>
    </modules>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Это shaker-multi-core ПОМ:

<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">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>sunshine.web</groupId>
        <artifactId>shaker-multi</artifactId>
        <version>0.0.1</version>
    </parent>

    <artifactId>shaker-multi-core</artifactId>
    <packaging>jar</packaging>

    <build>
        <plugins>
            <plugin><!-- jOOQ plugin--></plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency><!-- jOOQ dependency --></dependency>
    </dependencies>

</project>

Это shaker-multi-webapp ПОМ:

<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">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>sunshine.web</groupId>
        <artifactId>shaker-multi</artifactId>
        <version>0.0.1</version>
    </parent>

    <artifactId>shaker-multi-webapp</artifactId>
    <packaging>war</packaging>

    <build>
        <plugins>
            <plugin><!-- Tomcat local -->
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>sunshine.web</groupId>
            <artifactId>shaker-multi-core</artifactId>
            <version>0.0.1</version>
        </dependency>


        <dependency>
            <!-- JSP & Servlet dependencies -->
        </dependency>

    </dependencies> 
</project>

person watery    schedule 04.09.2014    source источник


Ответы (2)


Я предполагаю, что ваша структура папок выглядит следующим образом:

 +-- shaker-multi
         +--- pom.xml
         +--- shaker-multi-core
                     +-- pom.xml
         +--- shaker-multi-runnable
                     +-- pom.xml
         +--- shaker-multi-webapp
                     +-- pom.xml
  1. Кроме того, вы должны проверить, правильно ли работает ваш проект в команде и НЕ в Eclipse. Итак, вы должны перейти в корень вашего проекта (папка шейкер-мульти) и

    mvn чистый пакет

    Это не должно вызывать ошибок и т. д.

  2. Одна вещь, которая приходит мне на ум, это то, почему вы используете релизную версию вместо версии SNAPSHOT для своего проекта. Так 0.0.1 вместо 0.0.1-SNAPSHOT?

  3. Вещь, которую вы должны улучшить, - это определение плагина maven-compiler в вашем родителе:

    <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>3.1</version>
                 <configuration>
                     <source>1.7</source>
                     <target>1.7</target>
                     <encoding>UTF-8</encoding>
                 </configuration>
             </plugin>
         </plugins>
     </build>

Я бы предложил сделать это следующим образом:

   <build>
     <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
      </pluginManagement>
    </build>
  1. Кодировку можно решить лучше просто определите следующее в вашем pom:
<project>
  ...
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  ...
</project>

Вышеуказанное определяет значение по умолчанию для многих плагинов, таких как maven-compiler-plugin, maven-resources-plugin и т. д.

  1. часть из того, что ваша структура выглядит хорошо... я бы предложил одно небольшое улучшение, если вы определите зависимости между вашим модулем:
  <dependencies>
        <dependency>
            <groupId>sunshine.web</groupId>
            <artifactId>shaker-multi-core</artifactId>
            <version>0.0.1</version>
        </dependency>


        <dependency>
            <!-- JSP & Servlet dependencies -->
        </dependency>

    </dependencies> 

Я бы предложил определить межмодульные зависимости следующим образом:

  <dependencies>
        <dependency>
            <groupId>sunshine.web</groupId>
            <artifactId>shaker-multi-core</artifactId>
            <version>${project.version}</version>
        </dependency>


        <dependency>
            <!-- JSP & Servlet dependencies -->
        </dependency>

    </dependencies> 
person khmarbaise    schedule 05.09.2014
comment
Не могли бы вы добавить числовые или буквенные ссылки на ваши вопросы / предложения, чтобы я мог сослаться на них в своем комментарии, пожалуйста? - person watery; 05.09.2014
comment
1) Спасибо за предложение; 2) без особой причины; Я медленно подхожу к изучению Maven; 3), 4) и 5) это хорошо! Помимо всего этого, в моей настройке не было ничего плохого, проблема заключалась в том, что shaker-multi содержал все исходники модулей, кроме aggregator-parent-POM, в то время как в моем рабочем пространстве Eclipse был отдельный проект для каждого из этих подмодулей. Но я внес изменения в отдельные проекты, не зафиксировав их в svn и не вернув их обратно в проект-агрегатор, поэтому mvn install на последнем не удалось, потому что действительно не было файла web.xml. - person watery; 06.09.2014
comment
Я обновлю свой вопрос для ясности и добавлю ответ с техническим объяснением как можно скорее. Но ваш ответ содержит ценные предложения, поэтому +1 действительно заслужен! - person watery; 06.09.2014

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

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

Во-первых, после того, как я разбил единый проект на несколько модулей, в моем Eclipse Project Explorer возникла следующая ситуация:

+-- shaker-multi
        ^--- pom.xml
        ^--- shaker-multi-core
                    ^-- pom.xml
                    ^-- (other content)
        ^--- shaker-multi-runnable
                    ^-- pom.xml
                    ^-- (other content)
        ^--- shaker-multi-webapp
                    ^-- pom.xml
                    ^-- (other content)

+-- shaker-multi-core
            ^-- pom.xml

+-- shaker-multi-runnable
            ^-- pom.xml

+-- shaker-multi-webapp
            ^-- pom.xml

Каждый +-- представляет собой отдельный отдельный проект Eclipse. Каждый из них был отдельно взят из SVN (поэтому они были, по сути, отделены друг от друга).
Тогда я редактировал что-то в +-- shaker-multi-runnable и ожидал, что это сработает, когда я запускал Maven на +-- shaker-multi, без svncommiting первого и svnupdating второго.

Вот почему я продолжал получать ошибку в этом вопросе!

Правильный способ обработки таких проектов, если они исходят из изначально монолитного проекта:

  • разбивать код, ресурсы и т.д. по подпапкам;
  • фиксировать каждое изменение в репозитории;
  • чтобы удалить все задействованные проекты в Eclipse.

Затем перейдите на вкладку SVN Repositories среды IDE, разверните репозиторий с теперь разделенным проектом и выполните Извлечь как проект Maven для родительского проекта (того, в котором есть модули в виде подпапок).
Если вы, как и я, работаете с последней версией Subclipse, вам понадобится Maven Eclipse (m2e ) Коннектор SCM для subclipse 1.10 (svn 1.8) - сайт обновления (спасибо buluschek development, см. последние комментарии к этому сообщению), чтобы можно было выбрать путь к репозиторию в диалоговом окне Извлечь как проект Maven.

С его помощью вы указываете Eclipse извлечь весь проект из родительской папки, и Eclipse автоматически:

  1. извлекает все модули проекта Maven;
  2. создает проект, соответствующий родительскому проекту, где модули являются подпапками;
  3. создает отдельный проект для каждого отдельного модуля
  4. связывает каждый проект модуля с родительским проектом, так что каждое изменение в исходном коде модуля, ресурсе, POM и т. д. мгновенно отражается в папках родительского проекта.

Этот пункт (4) является ключевым здесь: хотя есть несколько проектов, они были связаны друг с другом (я думаю, то же самое можно сделать, вручную извлекая каждую папку модуля, хотя я не знаю, как).

После этого все проблемы с Maven у меня исчезли.

person watery    schedule 29.09.2014