use of com.google.cloud.tools.opensource.classpath.LinkageProblem in project cloud-opensource-java by GoogleCloudPlatform.
the class LinkageMonitor method messageForFixedErrors.
/**
* Returns a message on {@code fixedProblems}.
*/
@VisibleForTesting
static String messageForFixedErrors(Set<LinkageProblem> fixedProblems) {
int problemSize = fixedProblems.size();
StringBuilder message = new StringBuilder("The following problem" + (problemSize > 1 ? "s" : "") + " in the baseline no longer appear in the snapshot:\n");
for (LinkageProblem problem : fixedProblems) {
message.append(" " + problem.formatSymbolProblem() + "\n");
}
return message.toString();
}
use of com.google.cloud.tools.opensource.classpath.LinkageProblem in project cloud-opensource-java by GoogleCloudPlatform.
the class LinkageMonitor method main.
public static void main(String[] arguments) throws RepositoryException, IOException, MavenRepositoryException, ModelBuildingException {
CommandLine commandLine = parseCommandLine(arguments);
String bomCoordinates = commandLine.getArgList().get(0);
List<String> coordinatesElements = Splitter.on(':').splitToList(bomCoordinates);
if (coordinatesElements.size() != 2) {
logger.severe("Please specify BOM coordinates without version. Example:" + " com.google.cloud:libraries-bom");
System.exit(1);
}
Set<LinkageProblem> newLinkageProblems = new LinkageMonitor().run(coordinatesElements.get(0), coordinatesElements.get(1));
int errorSize = newLinkageProblems.size();
if (errorSize > 0) {
logger.severe(String.format("Found %d new linkage error%s", errorSize, errorSize > 1 ? "s" : ""));
logger.info("For the details of the linkage errors, see " + "https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/Linkage-Checker-Messages");
// notify CI tools of the failure
System.exit(1);
} else {
logger.info("No new problem found");
}
}
use of com.google.cloud.tools.opensource.classpath.LinkageProblem 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();
}
use of com.google.cloud.tools.opensource.classpath.LinkageProblem in project cloud-opensource-java by GoogleCloudPlatform.
the class MaximumLinkageErrorsTest method testForNewLinkageErrors.
@Test
public void testForNewLinkageErrors() throws IOException, MavenRepositoryException, RepositoryException {
// Not using RepositoryUtility.findLatestCoordinates, which may return a snapshot version
String version = findLatestNonSnapshotVersion();
String baselineCoordinates = "com.google.cloud:libraries-bom:" + version;
Bom baseline = Bom.readBom(baselineCoordinates);
Path bomFile = Paths.get("../cloud-oss-bom/pom.xml");
Bom bom = Bom.readBom(bomFile);
ImmutableSet<LinkageProblem> oldProblems = LinkageChecker.create(baseline).findLinkageProblems();
LinkageChecker checker = LinkageChecker.create(bom);
ImmutableSet<LinkageProblem> currentProblems = checker.findLinkageProblems();
// This only tests for newly missing methods, not new invocations of
// previously missing methods.
Set<LinkageProblem> newProblems = Sets.difference(currentProblems, oldProblems);
// Appengine-api-1.0-sdk is known to contain linkage errors because it shades dependencies
// https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/441
newProblems = newProblems.stream().filter(problem -> !hasLinkageProblemFromArtifactId(problem, "appengine-api-1.0-sdk")).collect(Collectors.toSet());
// Check that no new linkage errors have been introduced since the baseline
StringBuilder message = new StringBuilder("Baseline BOM: " + baselineCoordinates + "\n");
if (!newProblems.isEmpty()) {
message.append("Newly introduced problems:\n");
message.append(LinkageProblem.formatLinkageProblems(newProblems, null));
Assert.fail(message.toString());
}
}
use of com.google.cloud.tools.opensource.classpath.LinkageProblem 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;
}
Aggregations