From 54b0941e8eae0cf463093bc3c36d5f4346e34b60 Mon Sep 17 00:00:00 2001 From: cesarsotovalero Date: Wed, 25 Nov 2020 17:41:15 +0100 Subject: [PATCH] Fix https://github.com/castor-software/depclean/issues/21 --- .../DefaultProjectDependencyAnalyzer.java | 24 ++++----- .../analysis/ProjectDependencyAnalysis.java | 8 +-- .../java/se/kth/depclean/DepCleanMojo.java | 51 ++++++++++++------- .../kth/depclean/util/json/NodeAdapter.java | 5 +- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java index 5a2f2051..34fefca2 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java @@ -16,6 +16,13 @@ */ package se.kth.depclean.core.analysis; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import se.kth.depclean.core.analysis.asm.ASMDependencyAnalyzer; +import se.kth.depclean.core.analysis.graph.DefaultCallGraph; + import java.io.File; import java.io.IOException; import java.net.URL; @@ -29,29 +36,22 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; - -import se.kth.depclean.core.analysis.asm.ASMDependencyAnalyzer; -import se.kth.depclean.core.analysis.graph.DefaultCallGraph; - @Component(role = ProjectDependencyAnalyzer.class) public class DefaultProjectDependencyAnalyzer implements ProjectDependencyAnalyzer { + public static final String SEPARATOR = "-------------------------------------------------------"; /** * ClassAnalyzer */ @Requirement - private ClassAnalyzer classAnalyzer = new DefaultClassAnalyzer(); + private final ClassAnalyzer classAnalyzer = new DefaultClassAnalyzer(); /** * DependencyAnalyzer */ @Requirement - private DependencyAnalyzer dependencyAnalyzer = new ASMDependencyAnalyzer(); + private final DependencyAnalyzer dependencyAnalyzer = new ASMDependencyAnalyzer(); // ProjectDependencyAnalyzer methods -------------------------------------- @@ -60,7 +60,6 @@ public class DefaultProjectDependencyAnalyzer implements ProjectDependencyAnalyz */ public ProjectDependencyAnalysis analyze(MavenProject project) throws ProjectDependencyAnalyzerException { try { - // map of [dependency] -> [classes] Map> artifactClassMap = buildArtifactClassMap(project); @@ -70,6 +69,7 @@ public ProjectDependencyAnalysis analyze(MavenProject project) throws ProjectDep System.out.println("DIRECT DEPENDENCIES: " + declaredArtifacts); // transitive dependencies of the project + System.out.println(SEPARATOR); Set transitiveArtifacts = removeAll(project.getArtifacts(), declaredArtifacts); System.out.println("TRANSITIVE DEPENDENCIES: " + transitiveArtifacts); @@ -93,7 +93,7 @@ public ProjectDependencyAnalysis analyze(MavenProject project) throws ProjectDep /* ******************** call graph analysis ******************** */ System.out.println(SEPARATOR); - System.out.println("USED ARTIFACTS:" + usedArtifacts); + System.out.println("USED DEPENDENCIES: " + usedArtifacts); System.out.println(SEPARATOR); /* ******************** results as statically used at the bytecode *********************** */ diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysis.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysis.java index b09d0b1f..113b50b4 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysis.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysis.java @@ -19,18 +19,19 @@ * under the License. */ +import org.apache.maven.artifact.Artifact; + import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; -import org.apache.maven.artifact.Artifact; - /** * Project dependencies analysis result. */ public class ProjectDependencyAnalysis { + // fields ----------------------------------------------------------------- private final Set usedDeclaredArtifacts; @@ -45,7 +46,8 @@ public ProjectDependencyAnalysis() { this(null, null, null); } - public ProjectDependencyAnalysis(Set usedDeclaredArtifacts, Set usedUndeclaredArtifacts, + public ProjectDependencyAnalysis(Set usedDeclaredArtifacts, + Set usedUndeclaredArtifacts, Set unusedDeclaredArtifacts) { this.usedDeclaredArtifacts = safeCopy(usedDeclaredArtifacts); this.usedUndeclaredArtifacts = safeCopy(usedUndeclaredArtifacts); diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java index 2664c4ec..e0ed97cb 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java @@ -200,7 +200,8 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } - /* Get the size of the dependencies */ + + /* Get the size of all the dependencies */ Map sizeOfDependencies = new HashMap<>(); Iterator iterator = FileUtils.iterateFiles( new File( @@ -270,15 +271,10 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } + // TODO Fix: The used transitive dependencies induced by inherited dependencies should be considered as used inherited for (Artifact artifact : usedTransitiveArtifacts) { String artifactCoordinates = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(); - if (declaredArtifactsCoordinates.contains(artifactCoordinates)) { - // the artifact is declared in the pom - usedTransitiveArtifactsCoordinates.add(artifactCoordinates + ":" + artifact.getScope()); - } else { - // the artifact is inherited - usedInheritedArtifactsCoordinates.add(artifactCoordinates + ":" + artifact.getScope()); - } + usedTransitiveArtifactsCoordinates.add(artifactCoordinates + ":" + artifact.getScope()); } // --- unused dependencies @@ -297,15 +293,10 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } + // TODO Fix: The unused transitive dependencies induced by inherited dependencies should be considered as unused inherited for (Artifact artifact : unusedTransitiveArtifacts) { String artifactCoordinates = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(); - if (declaredArtifactsCoordinates.contains(artifactCoordinates)) { - // the artifact is declared in the pom - unusedTransitiveArtifactsCoordinates.add(artifactCoordinates + ":" + artifact.getScope()); - } else { - // the artifact is inherited - unusedInheritedArtifactsCoordinates.add(artifactCoordinates + ":" + artifact.getScope()); - } + unusedTransitiveArtifactsCoordinates.add(artifactCoordinates + ":" + artifact.getScope()); } /* Ignoring dependencies from the analysis */ @@ -485,14 +476,33 @@ public void execute() throws MojoExecutionException, MojoFailureException { private void printDependencies(Map sizeOfDependencies, Set dependencies) { dependencies .stream() - .sorted(Comparator.comparing(o -> sizeOfDependencies.get(o.split(":")[1] + "-" + o.split(":")[2] + ".jar"))) + .sorted(Comparator.comparing(o -> getSizeOfDependency(sizeOfDependencies, o))) .collect(Collectors.toCollection(LinkedList::new)) .descendingIterator() .forEachRemaining(s -> printString("\t" + s + " (" + getSize(s, sizeOfDependencies) + ")")); } /** - * Get the size of the dependency in humnan readable format. + * Utility method to obtain the size of a dependency from a map of dependency -> size. If the size of the dependency + * cannot be obtained form the map (no key with the name of the dependency exists), then it returns 0. + * + * @param sizeOfDependencies A map of dependency -> size. + * @param dependency The coordinates of a dependency. + * @return The size of the dependency if its name is a key in the map, otherwise it returns 0. + */ + private Long getSizeOfDependency(Map sizeOfDependencies, String dependency) { + Long size = sizeOfDependencies.get(dependency.split(":")[1] + "-" + dependency.split(":")[2] + ".jar"); + if (size != null) { + return size; + } else { + // The name of the dependency does not match with the name of the download jar, so we keep assume the size + // cannot be obtained and return 0. + return Long.valueOf(0); + } + } + + /** + * Get the size of the dependency in human readable format. * * @param dependency The dependency. * @param sizeOfDependencies A map with the size of the dependencies, keys are stored as the downloaded jar file @@ -501,7 +511,12 @@ private void printDependencies(Map sizeOfDependencies, Set */ private String getSize(String dependency, Map sizeOfDependencies) { String dep = dependency.split(":")[1] + "-" + dependency.split(":")[2] + ".jar"; - return FileUtils.byteCountToDisplaySize(sizeOfDependencies.get(dep)); + if (sizeOfDependencies.containsKey(dep)) { + return FileUtils.byteCountToDisplaySize(sizeOfDependencies.get(dep)); + } else { + // The size cannot be obtained. + return "unknown"; + } } /** diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/json/NodeAdapter.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/json/NodeAdapter.java index f763e89c..1c96f70b 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/json/NodeAdapter.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/json/NodeAdapter.java @@ -41,9 +41,12 @@ public void write(JsonWriter jsonWriter, Node node) throws IOException { String coordinates = node.getGroupId() + ":" + node.getArtifactId() + ":" + node.getVersion() + ":" + node.getScope(); String dependencyJar = node.getArtifactId() + "-" + node.getVersion() + ".jar"; jsonWriter.beginObject() - .name("coordinates") + .name("id") .jsonValue("\"" + node.getArtifactCanonicalForm() + "\"") + .name("coordinates") + .jsonValue("\"" + node.getGroupId() + ":" + node.getArtifactId() + ":" + node.getVersion() + "\"") + .name("groupId") .jsonValue("\"" + node.getGroupId() + "\"")