Maven не разрешает локальный родительский POM

Это интересная проблема, и я не могу сказать, делаю ли я что-то не так или это ограничение Maven.

Простейшая версия сценария состоит в том, что есть родительское POM, одно дочернее POM и POM агрегирования. Агрегирование POM просто объединяет модули.

Когда я устанавливаю POM агрегации, он не обнаруживает зависимости дочернего POM от родительского POM. Я предпочел бы не иметь относительный путь и должен быть возможен из моего понимания артефактов Maven.

Любое понимание будет с благодарностью. Благодарю.

Это родитель Uber (не говоря уже о том, что в нем ничего нет)

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>my.group</groupId>
    <artifactId>parent-uber</artifactId>
    <version>0.0.2-SNAPSHOT</version>
    <packaging>pom</packaging>

</project>

Это ребенок

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>my.group</groupId>
        <artifactId>parent-uber</artifactId>
        <version>0.0.2-SNAPSHOT</version>
    </parent>

    <groupId>my.group</groupId>
    <artifactId>parent-java</artifactId>
    <packaging>pom</packaging>

    <properties>
    </properties>

    <build>
        <!-- To define the plugin version in your parent POM -->
        <pluginManagement>
            <plugins>
                <!-- All projects that extend this should have valid JavaDoc built-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>attach-javadocs</id>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>    
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.1</version>
            </dependency>    
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.4</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

А для полноты агрегатор:

<project>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>my.group</groupId>
        <artifactId>_maven-integration-aggregator</artifactId>
        <version>0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- parent aggregator -->
    </parent>

    <groupId>my.group.maven</groupId>
    <artifactId>_poms-aggregator</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>parent-uber</module>
        <module>parent-java</module>
    </modules>

</project>

Ошибка:

org.apache.maven.model.resolution.UnresolvableModelException: Could not find artifact my.group:parent-uber:pom:0.0.2-SNAPSHOT
    at org.apache.maven.project.ProjectModelResolver.resolveModel(ProjectModelResolver.java:159)
    at org.apache.maven.model.building.DefaultModelBuilder.readParentExternally(DefaultModelBuilder.java:817)
    at org.apache.maven.model.building.DefaultModelBuilder.readParent(DefaultModelBuilder.java:669)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:307)
    at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:411)
    at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:380)
    at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:496)
    at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:380)
    at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:344)
    at org.apache.maven.DefaultMaven.collectProjects(DefaultMaven.java:637)
    at org.apache.maven.DefaultMaven.getProjectsForMavenReactor(DefaultMaven.java:586)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:229)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:152)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:555)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not find artifact my.group:parent-uber:pom:0.0.2-SNAPSHOT
    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:459)
    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:262)
    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:239)
    at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:295)
    at org.apache.maven.project.ProjectModelResolver.resolveModel(ProjectModelResolver.java:155)
    ... 23 more
Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact my.parent:parent-uber:pom:0.0.2-SNAPSHOT
    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:449)
    ... 27 more

4 ответа

Вы можете решить эту проблему, добавив специальный профиль для построения только родительского.

В вашем ребенке пом добавить <relativePath /> к <parent> тег. Затем измените агрегатор.

Агрегатор пом:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>my.group.maven</groupId>
    <artifactId>_poms-aggregator</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <modules>
                <module>parent-uber</module>
                <module>parent-java</module>
            </modules>
        </profile>
        <profile>
            <id>prepare</id>
            <modules>
                <module>parent-uber</module>
            </modules>
        </profile>
    </profiles>

</project>

И используйте его для запуска сборки дважды, вот так:

mvn install -Pprepare
mvn install

Первая команда устанавливает pom родителей в локальный репозиторий, поэтому вторая команда не потерпит неудачу.

Но это решение работает, только если ваш родительский проект имеет ту же версию, что и дочерний. Но допустим, что вы выпустили родительскую версию 1.0 и теперь вы работаете над родительской версией 1.1-SNAPSHOT, но child использует выпущенную версию 1.0. Если вы сейчас удалите локальное хранилище, или кто-то еще клонирует ваш проект, создав -Pprepare не будет работать, так как это установит parent-uber:1.1-SNAPSHOT и ребенок все еще будет иметь неразрешенную зависимость.

Таким образом, чтобы это работало, вам понадобится внешний репозиторий (Nexus, Artifactory и т. Д.), В который вы выпустили parent-uber:1.0 и вам придется предоставить это репо в <repositories> пометка в детском пом.

Когда есть много дочерних проектов, часто рекомендуется поместить общие настройки в родительский pom, чтобы избежать дублирования кода. Поскольку хранилище является общим для всех проектов, вы можете захотеть поместить его в родительский. Но тогда, если у вас нет родителя, установленного локально, и вы пытаетесь установить child, тогда maven не знает, какой репозиторий он должен использовать для загрузки родителя. Чтобы избежать этой проблемы, вы можете добавить профиль с этим хранилищем в .m2/settings.xml и посоветуйте всем членам вашей команды сделать то же самое.

Согласно этому руководству, кажется, что родительская зависимость НЕ анализируется автоматически многомодульным реактором maven. Так как НИКАКАЯ родительская зависимость не указана в списке.

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

  1. зависимость проекта от другого модуля в сборке
  2. объявление плагина, где плагин - это другие модули в сборке
  3. зависимость плагина от другого модуля в сборке
  4. Создайте объявление расширения в другом модуле в порядке сборки, объявленном в элементе (если не применяется другое правило)

И я убедился, что maven действительно определяет порядок сборки, анализируя граф зависимостей, определенный тегами, между подмодулями.

Ну, я сделал это по-другому.

В моем случае я хотел "родителя", который тоже является "агрегатором".

Итак, я создал свой проект "родитель + агрегатор".

Это отрывок из pom.xml моего проекта "родитель + агрегатор":

<groupId>com.test</groupId>
<artifactId>parent-testproject</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

<modules>
    <module>../testprojectjpa</module>
    <module>../testprojectejb</module>
    <module>../testprojectweb</module>
    <module>../testprojectapp</module>
</modules>

<properties>
    <xstream.version>1.4.9</xstream.version>
    <dom4j.version>1.6.1</dom4j.version>
    <commons-lang.version>2.6</commons-lang.version>
    <commons-io.version>2.2</commons-io.version>
    <commons-beanutils.version>1.9.2</commons-beanutils.version>
    <commons-logging.version>1.1.2</commons-logging.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>${xstream.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>${dom4j.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>${commons-lang.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>${commons-io.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>${commons-beanutils.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>${commons-logging.version}</version>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

После этого я изменил "testprojectejb" для ссылки на "parent-testproject".

<parent>
    <groupId>com.test</groupId>
    <artifactId>parent-testproject</artifactId>
    <version>1.0.0</version>
    <!-- Find the project "parent + aggregator" that was compiled before of 
    the project testprojectejb -->
    <relativePath>../testproject/pom.xml</relativePath>
</parent>

<artifactId>testprojectejb</artifactId>
<packaging>ejb</packaging>
<name>Projeto testproject ejb</name>
<version>1.0.0</version>

Итак, когда я собираю "testproject" (parent-testproject), то все проекты создаются, включая родительский.

Я надеюсь, что это полезно.

В моем случае определенная версия родительского pom не совпадает с той, которую я упоминал в дочернем pom, и, следовательно, ошибка. Он начал работать нормально, как только я исправил версию на моем родительском pom.xml -

<version>2.1.0</version>

запись детского помпона выглядела как

<relativePath>../parent-pom</relativePath>

Я не знаю, является ли это решением вашей проблемы, но:

При указании родительского pom maven по умолчанию предполагает, что он находится в родительской папке. Это не ваш случай, поэтому вы должны либо переопределить относительный путь в родительском разделе вашего parent-java, чтобы указать ../parent-uberи пом будет решаться локально, или как <relativePath />и это будет решено удаленно.

Другие вопросы по тегам