Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -785,10 +785,10 @@ private void validateEffectiveDependencies(
prefix, "version", problems, errOn30, Version.V20, d.getVersion(), d.getManagementKey(), d);

/*
* TODO Extensions like Flex Mojos use custom scopes like "merged", "internal", "external", etc. In
* order to don't break backward-compat with those, only warn but don't error out.
* Extensions like Flex Mojos use custom scopes like "merged", "internal", "external", etc. In
* order to not break backward-compat with those, only warn but don't error out.
*/
validateEnum(
validateDependencyScope(
prefix,
"scope",
problems,
Expand All @@ -797,15 +797,11 @@ private void validateEffectiveDependencies(
d.getScope(),
d.getManagementKey(),
d,
"provided",
"compile",
"runtime",
"test",
"system");
false);

validateEffectiveModelAgainstDependency(prefix, problems, m, d, request);
} else {
validateEnum(
validateDependencyScope(
prefix,
"scope",
problems,
Expand All @@ -814,12 +810,7 @@ private void validateEffectiveDependencies(
d.getScope(),
d.getManagementKey(),
d,
"provided",
"compile",
"runtime",
"test",
"system",
"import");
true);
}
}
}
Expand Down Expand Up @@ -1462,6 +1453,58 @@ private boolean validateEnum(
return false;
}

@SuppressWarnings("checkstyle:parameternumber")
private boolean validateDependencyScope(
String prefix,
String fieldName,
ModelProblemCollector problems,
Severity severity,
Version version,
String scope,
String sourceHint,
InputLocationTracker tracker,
boolean isDependencyManagement) {
if (scope == null || scope.length() <= 0) {
return true;
}

String[] validScopes;
if (isDependencyManagement) {
validScopes = new String[] {"provided", "compile", "runtime", "test", "system", "import"};
} else {
validScopes = new String[] {"provided", "compile", "runtime", "test", "system"};
}

List<String> values = Arrays.asList(validScopes);

if (values.contains(scope)) {
return true;
}

// Provide a more helpful error message for the 'import' scope
if ("import".equals(scope) && !isDependencyManagement) {
addViolation(
problems,
severity,
version,
prefix + fieldName,
sourceHint,
"has scope 'import'. The 'import' scope is only valid in <dependencyManagement> sections.",
tracker);
} else {
addViolation(
problems,
severity,
version,
prefix + fieldName,
sourceHint,
"must be one of " + values + " but is '" + scope + "'.",
tracker);
}

return false;
}

@SuppressWarnings("checkstyle:parameternumber")
private boolean validateModelVersion(
ModelProblemCollector problems, String string, InputLocationTracker tracker, String... validVersions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ void testBadDependencyScope() throws Exception {
assertViolations(result, 0, 0, 2);

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

assertTrue(result.getWarnings().get(1).contains("test:g"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,17 @@ void testEqualsIdentity() {
void testToStringNullSafe() {
assertNotNull(new Model().toString());
}

@Test
void testPropertiesClear() {
// Test for issue #11552: NullPointerException when clearing properties
Model model = new Model();
model.addProperty("key1", "value1");
model.addProperty("key2", "value2");
assertEquals(2, model.getProperties().size());

// This should not throw NullPointerException
model.getProperties().clear();
assertEquals(0, model.getProperties().size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.maven.ProjectCycleException;
import org.apache.maven.RepositoryUtils;
import org.apache.maven.api.ArtifactCoordinates;
import org.apache.maven.api.Language;
Expand Down Expand Up @@ -504,10 +503,14 @@ List<ProjectBuildingResult> build(List<File> pomFiles, boolean recursive) throws
.findAny()
.orElse(null);
if (cycle != null) {
throw new RuntimeException(new ProjectCycleException(
final CycleDetectedException cde = (CycleDetectedException) cycle.getException();
throw new ProjectBuildingException(
null,
"The projects in the reactor contain a cyclic reference: " + cycle.getMessage(),
(CycleDetectedException) cycle.getException()));
null,
cde);
}

throw new ProjectBuildingException(results);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.io.File;
import java.util.List;

import org.apache.maven.model.building.ModelProblem;

/**
*/
public class ProjectBuildingException extends Exception {
Expand Down Expand Up @@ -59,7 +61,7 @@ protected ProjectBuildingException(String projectId, String message, File pomFil
}

public ProjectBuildingException(List<ProjectBuildingResult> results) {
super("Some problems were encountered while processing the POMs");
super(createMessage(results));
this.projectId = "";
this.results = results;
}
Expand Down Expand Up @@ -97,4 +99,84 @@ private static String createMessage(String message, String projectId, File pomFi
}
return buffer.toString();
}

private static String createMessage(List<ProjectBuildingResult> results) {
if (results == null || results.isEmpty()) {
return "Some problems were encountered while processing the POMs";
}

long totalProblems = 0;
long errorProblems = 0;

for (ProjectBuildingResult result : results) {
List<ModelProblem> problems = result.getProblems();
totalProblems += problems.size();

for (ModelProblem problem : problems) {
if (problem.getSeverity() != ModelProblem.Severity.WARNING) {
errorProblems++;
}
}
}

StringBuilder buffer = new StringBuilder(1024);
buffer.append(totalProblems);
buffer.append(totalProblems == 1 ? " problem was " : " problems were ");
buffer.append("encountered while processing the POMs");

if (errorProblems > 0) {
buffer.append(" (")
.append(errorProblems)
.append(" ")
.append(errorProblems > 1 ? "errors" : "error")
.append(")");
}

buffer.append(":\n");

for (ProjectBuildingResult result : results) {
if (!result.getProblems().isEmpty()) {
String projectInfo = result.getProjectId();
if (projectInfo.trim().isEmpty()) {
projectInfo =
result.getPomFile() != null ? result.getPomFile().getName() : "unknown project";
}

buffer.append("\n[").append(projectInfo).append("]\n");

for (ModelProblem problem : result.getProblems()) {
if (errorProblems > 0 && problem.getSeverity() == ModelProblem.Severity.WARNING) {
continue;
}

buffer.append(" [").append(problem.getSeverity()).append("] ");
buffer.append(problem.getMessage());

String location = "";
if (!problem.getSource().trim().isEmpty()) {
location = problem.getSource();
}
if (problem.getLineNumber() > 0) {
if (!location.isEmpty()) {
location += ", ";
}
location += "line " + problem.getLineNumber();
}
if (problem.getColumnNumber() > 0) {
if (!location.isEmpty()) {
location += ", ";
}
location += "column " + problem.getColumnNumber();
}

if (!location.isEmpty()) {
buffer.append(" @ ").append(location);
}
buffer.append("\n");
}
}
}

return buffer.toString();
}
}
Loading
Loading