Как правильно готовить maven с мультипроектами?
От: vsb Казахстан  
Дата: 04.07.19 14:32
Оценка:
Как-то мне сказали, что maven не хуже Gradle для мультипроектов. Не скажу, что мне так уж нравится Gradle, идеологически мне Maven ближе, но я не понимаю, как правильно делать там даже самые простейшие мультипроекты.

Как я делаю в Gradle:
Делаю родительский проект
Создаю в нём папки для дочерних проектов
Прописываю их в settings.gradle
В дочерних проектах проставляю зависимости друг от друга

Всё, оно просто работает. Я захожу в дочерний проект, пишу gradle build, он при необходимости собирает зависимые дочерние проекты (причём отслеживает изменения на уровне class-файлов, насколько я знаю), собирает текущий проект. Что может быть логичней и проще?

Как я пытаюсь делать в Maven по аналогичной схеме:
Делаю родительский проект:
<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>
    <groupId>multitest</groupId>
    <artifactId>multitest-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    
    <modules>
        <module>multitest-test1</module>
        <module>multitest-test2</module>
    </modules>
</project>

Создаю в нём папки multitest-test1 и multitest-test2 и делаю там дочерние проекты:
<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>multitest</groupId>
        <artifactId>multitest-parent</artifactId>
        <version>1.0-SNAPSHOT</version>        
    </parent>
    <artifactId>multitest-test1</artifactId>
</project>

<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>multitest</groupId>
        <artifactId>multitest-parent</artifactId>
        <version>1.0-SNAPSHOT</version>        
    </parent>
    <artifactId>multitest-test2</artifactId>
    
    <dependencies>
        <dependency>
            <groupId>multitest</groupId>
            <artifactId>multitest-test1</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>


Создаю классы где положено:
package multitest.test1;

public class Test1 {
    public static String CONSTANT = "constant-a";
    
    public static String method() {
        return "method-a";
    }
}

package multitest.test2;

import multitest.test1.Test1;

public class Test2 {
    public static void main(String[] args) {
        System.out.println(Test1.CONSTANT);
        System.out.println(Test1.method());
    }
}


Теперь я хочу хотя бы собрать test2 и чтобы оно сообразило, что надо собрать и test1, пошло и собрало.
C:\Users\Vladimir\Projects\test\multitest\multitest-test2>mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< multitest:multitest-test2 >----------------------
[INFO] Building multitest-test2 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[WARNING] The POM for multitest:multitest-test1:jar:1.0-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.319 s
[INFO] Finished at: 2019-07-04T20:23:33+06:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project multitest-test2: Could not resolve dependencies for project multitest:multitest-test2:jar:1.0-SNAPSHOT: Could not find artifact multitest:multitest-test1:jar:1.0-SNAPSHOT -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

В общем не получилось у него чего-то там найти. Если я запущу mvn build из родительской папки, то всё вроде как сбилдится, но я же хочу сбилдить конкретный дочерний проект (и все, от которых он зависит), а не все. Как запустить дочерний проект через mvn exec:java -Dexec.mainClass=multitest.test2.Test2 я вообще не понимаю.

Раньше я использовал Maven и такие ситуации решал следующим образом:

Заходим в родительский проект и выполняем mvn install

Теперь все jar-ки скопированы в кеш и вроде как с ними можно работать, т.е. зайти multitest-test2 и что-нибудь сбилдить или запустить.

Но у этого способа есть много минусов. Во-первых и в самых главных, он не отслеживает изменения в зависимых проектах, он просто использует те версии, которые в последний раз копировались в кеш. Т.е. если я сделаю mvn install, потом поменяю исходник в multitest-test1, потом перейду в multitest-test2 и буду его собирать, запускать и тд, то будет использоваться старая версия исходника. Нужно не забывать после каждой правки зависимости делать mvn install. Это очень неудобно.

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

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

В общем вопрос — можно ли сделать то, что я хочу, в Maven?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.