diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java
index b97064f3117f..27b29148e90e 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java
@@ -910,7 +910,7 @@ public void validateEffectiveModel(
validateStringNotEmpty("packaging", problems, Severity.ERROR, Version.BASE, model.getPackaging(), model);
- if (!model.getModules().isEmpty()) {
+ if (!model.getModules().isEmpty() || !model.getSubprojects().isEmpty()) {
if (!"pom".equals(model.getPackaging())) {
addViolation(
problems,
@@ -946,6 +946,30 @@ public void validateEffectiveModel(
model.getLocation("modules"));
}
}
+
+ for (int index = 0, size = model.getSubprojects().size(); index < size; index++) {
+ String subproject = model.getSubprojects().get(index);
+
+ boolean isBlankSubproject = true;
+ if (subproject != null) {
+ for (int charIndex = 0; charIndex < subproject.length(); charIndex++) {
+ if (!Character.isWhitespace(subproject.charAt(charIndex))) {
+ isBlankSubproject = false;
+ }
+ }
+ }
+
+ if (isBlankSubproject) {
+ addViolation(
+ problems,
+ Severity.ERROR,
+ Version.BASE,
+ "subprojects.subproject[" + index + "]",
+ null,
+ "has been specified without a path to the project directory.",
+ model.getLocation("subprojects"));
+ }
+ }
}
validateStringNotEmpty("version", problems, Severity.ERROR, Version.BASE, model.getVersion(), model);
diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java
index 6e8397d708da..6ed648334089 100644
--- a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java
+++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java
@@ -543,6 +543,24 @@ void testEmptyModule() throws Exception {
assertTrue(result.getErrors().get(0).contains("'modules.module[0]' has been specified without a path"));
}
+ @Test
+ void testInvalidAggregatorPackagingSubprojects() throws Exception {
+ SimpleProblemCollector result = validate("invalid-aggregator-packaging-subprojects-pom.xml");
+
+ assertViolations(result, 0, 1, 0);
+
+ assertTrue(result.getErrors().get(0).contains("Aggregator projects require 'pom' as packaging."));
+ }
+
+ @Test
+ void testEmptySubproject() throws Exception {
+ SimpleProblemCollector result = validate("empty-subproject.xml");
+
+ assertViolations(result, 0, 1, 0);
+
+ assertTrue(result.getErrors().get(0).contains("'subprojects.subproject[0]' has been specified without a path"));
+ }
+
@Test
void testDuplicatePlugin() throws Exception {
SimpleProblemCollector result = validateFile("duplicate-plugin.xml");
diff --git a/impl/maven-impl/src/test/resources/poms/validation/empty-subproject.xml b/impl/maven-impl/src/test/resources/poms/validation/empty-subproject.xml
new file mode 100644
index 000000000000..03e039f3e833
--- /dev/null
+++ b/impl/maven-impl/src/test/resources/poms/validation/empty-subproject.xml
@@ -0,0 +1,30 @@
+
+
+
+ 4.1.0
+ aid
+ gid
+ 0.1
+ pom
+
+
+
+
+
diff --git a/impl/maven-impl/src/test/resources/poms/validation/invalid-aggregator-packaging-subprojects-pom.xml b/impl/maven-impl/src/test/resources/poms/validation/invalid-aggregator-packaging-subprojects-pom.xml
new file mode 100644
index 000000000000..c4121ded842f
--- /dev/null
+++ b/impl/maven-impl/src/test/resources/poms/validation/invalid-aggregator-packaging-subprojects-pom.xml
@@ -0,0 +1,30 @@
+
+
+
+ 4.1.0
+ foo
+ foo
+ 99.44
+ jar
+
+
+ test-subproject
+
+