Как-то мне сказали, что 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?