Search in sources :

Example 6 with ClassPathEntry

use of com.google.cloud.tools.opensource.classpath.ClassPathEntry in project cloud-opensource-java by GoogleCloudPlatform.

the class LinkageMonitor method messageForNewErrors.

/**
 * Returns a message on {@code snapshotProblems} that do not exist in {@code baselineProblems}.
 */
@VisibleForTesting
static String messageForNewErrors(Set<LinkageProblem> snapshotProblems, Set<LinkageProblem> baselineProblems, ClassPathResult classPathResult) {
    Set<LinkageProblem> newProblems = Sets.difference(snapshotProblems, baselineProblems);
    Builder<ClassPathEntry> problematicJars = ImmutableSet.builder();
    ImmutableListMultimap<String, LinkageProblem> groupedBySymbolProblem = Multimaps.index(newProblems, problem -> problem.formatSymbolProblem());
    StringBuilder message = new StringBuilder("Newly introduced problem" + (groupedBySymbolProblem.keySet().size() > 1 ? "s" : "") + ":\n");
    for (String problem : groupedBySymbolProblem.keySet()) {
        message.append(problem + "\n");
        for (LinkageProblem linkageProblem : groupedBySymbolProblem.get(problem)) {
            // This is null for ClassNotFound error.
            if (linkageProblem.getTargetClass() != null) {
                problematicJars.add(linkageProblem.getTargetClass().getClassPathEntry());
            }
            ClassFile sourceClass = linkageProblem.getSourceClass();
            message.append(String.format("  referenced from %s (%s)\n", sourceClass.getBinaryName(), sourceClass.getClassPathEntry()));
            problematicJars.add(sourceClass.getClassPathEntry());
        }
    }
    message.append("\n");
    message.append(classPathResult.formatDependencyPaths(problematicJars.build()));
    return message.toString();
}
Also used : LinkageProblem(com.google.cloud.tools.opensource.classpath.LinkageProblem) ClassFile(com.google.cloud.tools.opensource.classpath.ClassFile) ClassPathEntry(com.google.cloud.tools.opensource.classpath.ClassPathEntry) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 7 with ClassPathEntry

use of com.google.cloud.tools.opensource.classpath.ClassPathEntry in project java-cloud-bom by googleapis.

the class BomContentTest method assertUniqueClasses.

/**
 * Asserts that the BOM only provides JARs which contains unique class names to the classpath.
 */
private static void assertUniqueClasses(List<Artifact> allArtifacts) throws InvalidVersionSpecificationException, IOException {
    StringBuilder errorMessageBuilder = new StringBuilder();
    ClassPathBuilder classPathBuilder = new ClassPathBuilder();
    ClassPathResult result = classPathBuilder.resolve(allArtifacts, false, DependencyMediation.MAVEN);
    // A Map of every class name to its artifact ID.
    HashMap<String, String> fullClasspathMap = new HashMap<>();
    for (ClassPathEntry classPathEntry : result.getClassPath()) {
        Artifact currentArtifact = classPathEntry.getArtifact();
        if (!currentArtifact.getGroupId().contains("google") || currentArtifact.getGroupId().contains("com.google.android") || currentArtifact.getGroupId().contains("com.google.cloud.bigtable") || currentArtifact.getArtifactId().startsWith("proto-") || currentArtifact.getArtifactId().equals("protobuf-javalite") || currentArtifact.getArtifactId().equals("appengine-testing")) {
            // See: https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/2226
            continue;
        }
        String artifactCoordinates = Artifacts.toCoordinates(currentArtifact);
        for (String className : classPathEntry.getFileNames()) {
            if (className.contains("javax.annotation") || className.contains("$") || className.equals("com.google.cloud.location.LocationsGrpc") || className.endsWith("package-info")) {
                // Ignore LocationsGrpc classes which are duplicated in generated grpc libraries.
                continue;
            }
            String previousArtifact = fullClasspathMap.get(className);
            if (previousArtifact != null) {
                String msg = String.format("Duplicate class %s found in classpath. Found in artifacts %s and %s.\n", className, previousArtifact, artifactCoordinates);
                errorMessageBuilder.append(msg);
            } else {
                fullClasspathMap.put(className, artifactCoordinates);
            }
        }
    }
    String error = errorMessageBuilder.toString();
    Assert.assertTrue("Failing test due to duplicate classes found on classpath:\n" + error, error.isEmpty());
}
Also used : HashMap(java.util.HashMap) ClassPathBuilder(com.google.cloud.tools.opensource.classpath.ClassPathBuilder) ClassPathResult(com.google.cloud.tools.opensource.classpath.ClassPathResult) ClassPathEntry(com.google.cloud.tools.opensource.classpath.ClassPathEntry) Artifact(org.eclipse.aether.artifact.Artifact)

Example 8 with ClassPathEntry

use of com.google.cloud.tools.opensource.classpath.ClassPathEntry in project cloud-opensource-java by GoogleCloudPlatform.

the class LinkageCheckTask method findLinkageErrors.

/**
 * Returns true iff {@code configuration}'s artifacts contain linkage errors.
 */
private boolean findLinkageErrors(Configuration configuration) throws IOException {
    ClassPathResult classPathResult = createClassPathResult(configuration.getResolvedConfiguration());
    ImmutableList.Builder<ClassPathEntry> classPathEntriesBuilder = ImmutableList.builder();
    for (ResolvedArtifact resolvedArtifact : configuration.getResolvedConfiguration().getResolvedArtifacts()) {
        ModuleVersionIdentifier moduleVersionId = resolvedArtifact.getModuleVersion().getId();
        DefaultArtifact artifact = new DefaultArtifact(moduleVersionId.getGroup(), moduleVersionId.getName(), resolvedArtifact.getClassifier(), resolvedArtifact.getExtension(), moduleVersionId.getVersion(), null, resolvedArtifact.getFile());
        classPathEntriesBuilder.add(new ClassPathEntry(artifact));
    }
    ImmutableList<ClassPathEntry> classPath = classPathEntriesBuilder.build();
    if (!classPath.isEmpty()) {
        String exclusionFileName = extension.getExclusionFile();
        Path exclusionFile = exclusionFileName == null ? null : Paths.get(exclusionFileName);
        if (exclusionFile != null && !exclusionFile.isAbsolute()) {
            // Relative path from the project root
            Path projectRoot = getProject().getRootDir().toPath();
            exclusionFile = projectRoot.resolve(exclusionFile).toAbsolutePath();
        }
        // TODO(suztomo): Specify correct entry points if reportOnlyReachable is true.
        LinkageChecker linkageChecker = LinkageChecker.create(classPath, classPath, exclusionFile);
        ImmutableSet<LinkageProblem> linkageProblems = linkageChecker.findLinkageProblems();
        ClassPathBuilder classPathBuilder = new ClassPathBuilder();
        LinkageProblemCauseAnnotator.annotate(classPathBuilder, classPathResult, linkageProblems);
        int errorCount = linkageProblems.size();
        // TODO(suztomo): Show the dependency paths to the problematic artifacts.
        if (errorCount > 0) {
            getLogger().error("Linkage Checker rule found {} error{}:\n{}", errorCount, errorCount > 1 ? "s" : "", LinkageProblem.formatLinkageProblems(linkageProblems, classPathResult));
            ResolutionResult result = configuration.getIncoming().getResolutionResult();
            ResolvedComponentResult root = result.getRoot();
            String dependencyPaths = dependencyPathsOfProblematicJars(root, linkageProblems);
            getLogger().error(dependencyPaths);
            getLogger().info("For the details of the linkage errors, see " + "https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/Linkage-Checker-Messages");
        }
        return errorCount > 0;
    }
    // When the configuration does not have any artifacts, there's no linkage error.
    return false;
}
Also used : AnnotatedClassPath(com.google.cloud.tools.opensource.classpath.AnnotatedClassPath) Path(java.nio.file.Path) DependencyPath(com.google.cloud.tools.opensource.dependencies.DependencyPath) ResolvedArtifact(org.gradle.api.artifacts.ResolvedArtifact) LinkageProblem(com.google.cloud.tools.opensource.classpath.LinkageProblem) ImmutableList(com.google.common.collect.ImmutableList) ResolutionResult(org.gradle.api.artifacts.result.ResolutionResult) ClassPathResult(com.google.cloud.tools.opensource.classpath.ClassPathResult) ClassPathBuilder(com.google.cloud.tools.opensource.classpath.ClassPathBuilder) ClassPathEntry(com.google.cloud.tools.opensource.classpath.ClassPathEntry) ModuleVersionIdentifier(org.gradle.api.artifacts.ModuleVersionIdentifier) LinkageChecker(com.google.cloud.tools.opensource.classpath.LinkageChecker) ResolvedComponentResult(org.gradle.api.artifacts.result.ResolvedComponentResult) DefaultArtifact(org.eclipse.aether.artifact.DefaultArtifact)

Example 9 with ClassPathEntry

use of com.google.cloud.tools.opensource.classpath.ClassPathEntry in project cloud-opensource-java by GoogleCloudPlatform.

the class LinkageCheckTask method dependencyPathsOfProblematicJars.

private String dependencyPathsOfProblematicJars(ResolvedComponentResult componentResult, Set<LinkageProblem> symbolProblems) {
    ImmutableSet.Builder<ClassPathEntry> problematicJars = ImmutableSet.builder();
    for (LinkageProblem problem : symbolProblems) {
        ClassFile targetClass = problem.getTargetClass();
        if (targetClass != null) {
            problematicJars.add(targetClass.getClassPathEntry());
        }
        ClassFile sourceClass = problem.getSourceClass();
        problematicJars.add(sourceClass.getClassPathEntry());
    }
    return "Problematic artifacts in the dependency tree:\n" + dependencyPathToArtifacts(componentResult, problematicJars.build());
}
Also used : LinkageProblem(com.google.cloud.tools.opensource.classpath.LinkageProblem) ClassFile(com.google.cloud.tools.opensource.classpath.ClassFile) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) ImmutableSet(com.google.common.collect.ImmutableSet) ClassPathEntry(com.google.cloud.tools.opensource.classpath.ClassPathEntry)

Example 10 with ClassPathEntry

use of com.google.cloud.tools.opensource.classpath.ClassPathEntry in project cloud-opensource-java by GoogleCloudPlatform.

the class LinkageMonitor method run.

/**
 * Returns new problems in the BOM specified by {@code groupId} and {@code artifactId}. This
 * method compares the latest release of the BOM and its snapshot version which uses artifacts in
 * {@link #localArtifacts}.
 */
private ImmutableSet<LinkageProblem> run(String groupId, String artifactId) throws RepositoryException, IOException, MavenRepositoryException, ModelBuildingException {
    String latestBomCoordinates = RepositoryUtility.findLatestCoordinates(repositorySystem, groupId, artifactId);
    logger.info("BOM Coordinates: " + latestBomCoordinates);
    Bom baseline = Bom.readBom(latestBomCoordinates);
    ImmutableSet<LinkageProblem> problemsInBaseline = LinkageChecker.create(baseline, null).findLinkageProblems();
    Bom snapshot = copyWithSnapshot(repositorySystem, session, baseline, localArtifacts);
    // Comparing coordinates because DefaultArtifact does not override equals
    ImmutableList<String> baselineCoordinates = coordinatesList(baseline.getManagedDependencies());
    ImmutableList<String> snapshotCoordinates = coordinatesList(snapshot.getManagedDependencies());
    if (baselineCoordinates.equals(snapshotCoordinates)) {
        logger.info("Snapshot is same as baseline. Not running comparison.");
        logger.info("Baseline coordinates: " + Joiner.on(";").join(baselineCoordinates));
        return ImmutableSet.of();
    }
    ImmutableList<Artifact> snapshotManagedDependencies = snapshot.getManagedDependencies();
    ClassPathResult classPathResult = (new ClassPathBuilder()).resolve(snapshotManagedDependencies, true, DependencyMediation.MAVEN);
    ImmutableList<ClassPathEntry> classpath = classPathResult.getClassPath();
    List<ClassPathEntry> entryPointJars = classpath.subList(0, snapshotManagedDependencies.size());
    ImmutableSet<LinkageProblem> problemsInSnapshot = LinkageChecker.create(classpath, ImmutableSet.copyOf(entryPointJars), null).findLinkageProblems();
    if (problemsInBaseline.equals(problemsInSnapshot)) {
        logger.info("Snapshot versions have the same " + problemsInBaseline.size() + " errors as baseline");
        return ImmutableSet.of();
    }
    Set<LinkageProblem> fixedProblems = Sets.difference(problemsInBaseline, problemsInSnapshot);
    if (!fixedProblems.isEmpty()) {
        logger.info(messageForFixedErrors(fixedProblems));
    }
    Set<LinkageProblem> newProblems = Sets.difference(problemsInSnapshot, problemsInBaseline);
    if (!newProblems.isEmpty()) {
        logger.severe(messageForNewErrors(problemsInSnapshot, problemsInBaseline, classPathResult));
    }
    return ImmutableSet.copyOf(newProblems);
}
Also used : Bom(com.google.cloud.tools.opensource.dependencies.Bom) LinkageProblem(com.google.cloud.tools.opensource.classpath.LinkageProblem) ClassPathResult(com.google.cloud.tools.opensource.classpath.ClassPathResult) ClassPathBuilder(com.google.cloud.tools.opensource.classpath.ClassPathBuilder) Artifact(org.eclipse.aether.artifact.Artifact) DefaultArtifact(org.eclipse.aether.artifact.DefaultArtifact) ClassPathEntry(com.google.cloud.tools.opensource.classpath.ClassPathEntry)

Aggregations

ClassPathEntry (com.google.cloud.tools.opensource.classpath.ClassPathEntry)17 Artifact (org.eclipse.aether.artifact.Artifact)12 ClassPathResult (com.google.cloud.tools.opensource.classpath.ClassPathResult)10 DependencyPath (com.google.cloud.tools.opensource.dependencies.DependencyPath)8 ClassPathBuilder (com.google.cloud.tools.opensource.classpath.ClassPathBuilder)7 LinkageProblem (com.google.cloud.tools.opensource.classpath.LinkageProblem)7 DefaultArtifact (org.eclipse.aether.artifact.DefaultArtifact)7 AnnotatedClassPath (com.google.cloud.tools.opensource.classpath.AnnotatedClassPath)4 ImmutableList (com.google.common.collect.ImmutableList)4 Path (java.nio.file.Path)4 ClassFile (com.google.cloud.tools.opensource.classpath.ClassFile)3 LinkageChecker (com.google.cloud.tools.opensource.classpath.LinkageChecker)3 ImmutableSet (com.google.common.collect.ImmutableSet)3 DependencyGraph (com.google.cloud.tools.opensource.dependencies.DependencyGraph)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 File (java.io.File)2 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 EnforcerRuleException (org.apache.maven.enforcer.rule.api.EnforcerRuleException)2 Dependency (org.eclipse.aether.graph.Dependency)2