in src/main/java/org/apache/nifi/NarDuplicateDependenciesMojo.java [91:203]
public void execute() throws MojoExecutionException, MojoFailureException {
try {
NarDependencyUtils.ensureSingleNarDependencyExists(project);
// build the project for the nar artifact
final ProjectBuildingRequest narRequest = new DefaultProjectBuildingRequest();
narRequest.setRepositorySession(repoSession);
narRequest.setSystemProperties(System.getProperties());
artifactHandlerManager.addHandlers(NarDependencyUtils.createNarHandlerMap(narRequest, project, projectBuilder));
// get the dependency tree
final DependencyNode root = dependencyCollectorBuilder.collectDependencyGraph(narRequest, null);
DependencyNode narParent = root.getChildren()
.stream()
.filter(child -> NarDependencyUtils.NAR.equals(child.getArtifact().getType()))
.findFirst()
.orElseThrow(() -> new MojoExecutionException("Project does not have any NAR dependencies."));
getLog().info("Analyzing dependencies of " + narRequest.getProject().getFile().getPath());
// all compiled dependencies except inherited from parent
Map<String, List<Artifact>> directDependencies = new HashMap<>();
root.accept(new DependencyNodeVisitor() {
final Stack<Artifact> hierarchy = new Stack<>();
@Override
public boolean visit(DependencyNode node) {
if (node == root) {
return true;
}
Artifact artifact = node.getArtifact();
hierarchy.push(artifact);
if (NarDependencyUtils.COMPILE_STRING.equals(artifact.getScope()) && !NarDependencyUtils.NAR.equals(artifact.getType())) {
directDependencies.put(artifact.toString(), new ArrayList<>(hierarchy));
return true;
}
return false;
}
@Override
public boolean endVisit(DependencyNode node) {
if (node != root) {
hierarchy.pop();
}
return true;
}
});
Map<String, List<String>> errors = new HashMap<>();
narParent.accept(new DependencyNodeVisitor() {
final Stack<Artifact> hierarchy = new Stack<>();
@Override
public boolean visit(DependencyNode node) {
Artifact artifact = node.getArtifact();
hierarchy.push(artifact);
if (NarDependencyUtils.COMPILE_STRING.equals(artifact.getScope()) && directDependencies.containsKey(artifact.toString())) {
StringBuilder sb = new StringBuilder().append(root.getArtifact()).append(" (this nar)").append(System.lineSeparator());
List<Artifact> otherHierarchy = directDependencies.get(artifact.toString());
// print other hierarchy
for (int i = 0; i < otherHierarchy.size(); i++) {
sb.append(indent(i)).append(otherHierarchy.get(i));
// print the last artifact in the hierarchy
if (i == otherHierarchy.size() - 1) {
sb.append(" (duplicate)");
}
sb.append(System.lineSeparator());
}
// print this hierarchy
for (int i = 0; i < hierarchy.size(); i++) {
sb.append(indent(i)).append(hierarchy.get(i));
// print the last artifact in the hierarchy
if (i == hierarchy.size() - 1) {
sb.append(" (already included here)");
}
sb.append(System.lineSeparator());
}
errors.computeIfAbsent(artifact.toString(), k -> new ArrayList<>()).add(sb.toString());
}
return true;
}
@Override
public boolean endVisit(DependencyNode node) {
hierarchy.pop();
return true;
}
});
for (Map.Entry<String, List<String>> entry : errors.entrySet()) {
StringBuilder sb = new StringBuilder().append(entry.getKey()).append(" is already included in the nar");
if (entry.getValue().size() > 1) {
sb.append(" multiple times");
}
sb.append(":");
for (String error : entry.getValue()) {
sb.append(System.lineSeparator()).append(error);
}
getLog().error(sb.toString());
}
if (!errors.isEmpty()) {
getLog().info("Consider changing the scope from \"compile\" to \"provided\" or exclude it in case it's a transitive dependency.");
throw new MojoFailureException("Found duplicate dependencies");
}
} catch (ProjectBuildingException | DependencyCollectorBuilderException e) {
throw new MojoExecutionException("Cannot build project dependency tree", e);
}
}