Skip to content

Commit c8519ab

Browse files
committed
Improve dependency scope validation error messages for import scope
- Add context-aware error messages when 'import' scope is used incorrectly - Provide clear guidance that 'import' scope is only valid in <dependencyManagement> sections - Enhance both Maven 3 (compat) and Maven 4 (impl) implementations for consistency - Update tests to verify the improved error messages - Addresses confusion reported in faktorips/faktorips.base#70 Before: 'dependencies.dependency.scope' must be one of [provided, compile, runtime, test, system] but is 'import'. After: 'dependencies.dependency.scope' must be one of [provided, compile, runtime, test, system] but is 'import'. The 'import' scope is only valid in <dependencyManagement> sections and requires <type>pom</type>.
1 parent 7c23404 commit c8519ab

File tree

5 files changed

+193
-17
lines changed

5 files changed

+193
-17
lines changed

IMPROVEMENT_SUMMARY.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Maven Dependency Scope Validation Improvement
2+
3+
## Issue
4+
GitHub issue: https://github.com/faktorips/faktorips.base/issues/70
5+
6+
The issue reported a confusing Maven warning message:
7+
```
8+
Warning: 'dependencies.dependency.scope' for org.faktorips:eclipse-platform-dependencies:pom must be one of [provided, compile, runtime, test, system] but is 'import'.
9+
```
10+
11+
This message is misleading because it suggests that `import` scope is never valid, when in fact it's valid in `<dependencyManagement>` sections with `<type>pom</type>`.
12+
13+
## Root Cause
14+
The Maven model validator was using a generic error message that didn't provide context about when the `import` scope is valid. The validation logic correctly distinguished between regular dependencies and dependency management, but the error message didn't reflect this distinction.
15+
16+
## Solution
17+
Improved the error message to provide more helpful guidance when the `import` scope is used incorrectly:
18+
19+
### Before
20+
```
21+
'dependencies.dependency.scope' must be one of [provided, compile, runtime, test, system] but is 'import'.
22+
```
23+
24+
### After
25+
```
26+
'dependencies.dependency.scope' must be one of [provided, compile, runtime, test, system] but is 'import'. The 'import' scope is only valid in <dependencyManagement> sections and requires <type>pom</type>.
27+
```
28+
29+
## Changes Made
30+
31+
### 1. compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
32+
- Added new `validateDependencyScope()` method that provides context-aware error messages
33+
- Replaced calls to `validateEnum()` with `validateDependencyScope()` for dependency scope validation
34+
- Enhanced error message specifically for `import` scope misuse
35+
36+
### 2. impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java
37+
- Added similar improvements to the Maven 4 implementation
38+
- Maintained consistency between Maven 3 and Maven 4 validation behavior
39+
40+
### 3. Test Updates
41+
- Updated existing tests to verify the improved error message
42+
- Added assertions to check for the helpful guidance text
43+
44+
## Benefits
45+
1. **Clearer guidance**: Users now understand when `import` scope is valid
46+
2. **Faster resolution**: Developers can quickly identify the correct solution
47+
3. **Better developer experience**: Reduces confusion and debugging time
48+
4. **Consistent behavior**: Both Maven 3 and Maven 4 implementations provide the same helpful messages
49+
50+
## Example Usage
51+
The improved message helps users understand that they should move their `import` scope dependency from:
52+
53+
```xml
54+
<dependencies>
55+
<dependency>
56+
<groupId>org.faktorips</groupId>
57+
<artifactId>eclipse-platform-dependencies</artifactId>
58+
<version>26.1.0-SNAPSHOT</version>
59+
<type>pom</type>
60+
<scope>import</scope> <!-- ❌ Invalid here -->
61+
</dependency>
62+
</dependencies>
63+
```
64+
65+
To:
66+
67+
```xml
68+
<dependencyManagement>
69+
<dependencies>
70+
<dependency>
71+
<groupId>org.faktorips</groupId>
72+
<artifactId>eclipse-platform-dependencies</artifactId>
73+
<version>26.1.0-SNAPSHOT</version>
74+
<type>pom</type>
75+
<scope>import</scope> <!-- ✅ Valid here -->
76+
</dependency>
77+
</dependencies>
78+
</dependencyManagement>
79+
```

compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ private void validateEffectiveDependencies(
788788
* TODO Extensions like Flex Mojos use custom scopes like "merged", "internal", "external", etc. In
789789
* order to don't break backward-compat with those, only warn but don't error out.
790790
*/
791-
validateEnum(
791+
validateDependencyScope(
792792
prefix,
793793
"scope",
794794
problems,
@@ -797,15 +797,11 @@ private void validateEffectiveDependencies(
797797
d.getScope(),
798798
d.getManagementKey(),
799799
d,
800-
"provided",
801-
"compile",
802-
"runtime",
803-
"test",
804-
"system");
800+
false);
805801

806802
validateEffectiveModelAgainstDependency(prefix, problems, m, d, request);
807803
} else {
808-
validateEnum(
804+
validateDependencyScope(
809805
prefix,
810806
"scope",
811807
problems,
@@ -814,12 +810,7 @@ private void validateEffectiveDependencies(
814810
d.getScope(),
815811
d.getManagementKey(),
816812
d,
817-
"provided",
818-
"compile",
819-
"runtime",
820-
"test",
821-
"system",
822-
"import");
813+
true);
823814
}
824815
}
825816
}
@@ -1462,6 +1453,59 @@ private boolean validateEnum(
14621453
return false;
14631454
}
14641455

1456+
@SuppressWarnings("checkstyle:parameternumber")
1457+
private boolean validateDependencyScope(
1458+
String prefix,
1459+
String fieldName,
1460+
ModelProblemCollector problems,
1461+
Severity severity,
1462+
Version version,
1463+
String scope,
1464+
String sourceHint,
1465+
InputLocationTracker tracker,
1466+
boolean isDependencyManagement) {
1467+
if (scope == null || scope.length() <= 0) {
1468+
return true;
1469+
}
1470+
1471+
String[] validScopes;
1472+
if (isDependencyManagement) {
1473+
validScopes = new String[] {"provided", "compile", "runtime", "test", "system", "import"};
1474+
} else {
1475+
validScopes = new String[] {"provided", "compile", "runtime", "test", "system"};
1476+
}
1477+
1478+
List<String> values = Arrays.asList(validScopes);
1479+
1480+
if (values.contains(scope)) {
1481+
return true;
1482+
}
1483+
1484+
// Provide a more helpful error message for the 'import' scope
1485+
if ("import".equals(scope) && !isDependencyManagement) {
1486+
addViolation(
1487+
problems,
1488+
severity,
1489+
version,
1490+
prefix + fieldName,
1491+
sourceHint,
1492+
"must be one of " + values + " but is '" + scope + "'. "
1493+
+ "The 'import' scope is only valid in <dependencyManagement> sections and requires <type>pom</type>.",
1494+
tracker);
1495+
} else {
1496+
addViolation(
1497+
problems,
1498+
severity,
1499+
version,
1500+
prefix + fieldName,
1501+
sourceHint,
1502+
"must be one of " + values + " but is '" + scope + "'.",
1503+
tracker);
1504+
}
1505+
1506+
return false;
1507+
}
1508+
14651509
@SuppressWarnings("checkstyle:parameternumber")
14661510
private boolean validateModelVersion(
14671511
ModelProblemCollector problems, String string, InputLocationTracker tracker, String... validVersions) {

compat/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ void testBadDependencyScope() throws Exception {
355355
assertViolations(result, 0, 0, 2);
356356

357357
assertTrue(result.getWarnings().get(0).contains("test:f"));
358+
// Check that the import scope error message is more helpful
359+
assertTrue(result.getWarnings().get(0).contains("The 'import' scope is only valid in <dependencyManagement> sections"));
358360

359361
assertTrue(result.getWarnings().get(1).contains("test:g"));
360362
}

impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ private void validateEffectiveDependencies(
12251225
*/
12261226
ScopeManager scopeManager =
12271227
InternalSession.from(session).getSession().getScopeManager();
1228-
validateEnum(
1228+
validateDependencyScope(
12291229
prefix,
12301230
"scope",
12311231
problems,
@@ -1237,7 +1237,8 @@ private void validateEffectiveDependencies(
12371237
scopeManager.getDependencyScopeUniverse().stream()
12381238
.map(DependencyScope::getId)
12391239
.distinct()
1240-
.toArray(String[]::new));
1240+
.toArray(String[]::new),
1241+
false);
12411242

12421243
validateEffectiveModelAgainstDependency(prefix, problems, model, dependency);
12431244
} else {
@@ -1247,7 +1248,7 @@ private void validateEffectiveDependencies(
12471248
.map(DependencyScope::getId)
12481249
.collect(Collectors.toCollection(HashSet::new));
12491250
scopes.add("import");
1250-
validateEnum(
1251+
validateDependencyScope(
12511252
prefix,
12521253
"scope",
12531254
problems,
@@ -1256,7 +1257,8 @@ private void validateEffectiveDependencies(
12561257
dependency.getScope(),
12571258
SourceHint.dependencyManagementKey(dependency),
12581259
dependency,
1259-
scopes.toArray(new String[0]));
1260+
scopes.toArray(new String[0]),
1261+
true);
12601262
}
12611263
}
12621264
}
@@ -1993,6 +1995,53 @@ private boolean validateEnum(
19931995
return false;
19941996
}
19951997

1998+
@SuppressWarnings("checkstyle:parameternumber")
1999+
private boolean validateDependencyScope(
2000+
String prefix,
2001+
String fieldName,
2002+
ModelProblemCollector problems,
2003+
Severity severity,
2004+
Version version,
2005+
String scope,
2006+
@Nullable SourceHint sourceHint,
2007+
InputLocationTracker tracker,
2008+
String[] validScopes,
2009+
boolean isDependencyManagement) {
2010+
if (scope == null || scope.isEmpty()) {
2011+
return true;
2012+
}
2013+
2014+
List<String> values = Arrays.asList(validScopes);
2015+
2016+
if (values.contains(scope)) {
2017+
return true;
2018+
}
2019+
2020+
// Provide a more helpful error message for the 'import' scope
2021+
if ("import".equals(scope) && !isDependencyManagement) {
2022+
addViolation(
2023+
problems,
2024+
severity,
2025+
version,
2026+
prefix + fieldName,
2027+
sourceHint,
2028+
"must be one of " + values + " but is '" + scope + "'. "
2029+
+ "The 'import' scope is only valid in <dependencyManagement> sections and requires <type>pom</type>.",
2030+
tracker);
2031+
} else {
2032+
addViolation(
2033+
problems,
2034+
severity,
2035+
version,
2036+
prefix + fieldName,
2037+
sourceHint,
2038+
"must be one of " + values + " but is '" + scope + "'.",
2039+
tracker);
2040+
}
2041+
2042+
return false;
2043+
}
2044+
19962045
@SuppressWarnings("checkstyle:parameternumber")
19972046
private boolean validateModelVersion(
19982047
Session session,

impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ void testBadDependencyScope() throws Exception {
410410
assertViolations(result, 0, 0, 2);
411411

412412
assertTrue(result.getWarnings().get(0).contains("groupId='test', artifactId='f'"));
413+
// Check that the import scope error message is more helpful
414+
assertTrue(result.getWarnings().get(0).contains("The 'import' scope is only valid in <dependencyManagement> sections"));
413415

414416
assertTrue(result.getWarnings().get(1).contains("groupId='test', artifactId='g'"));
415417
}

0 commit comments

Comments
 (0)