From 1124a8ecdbc8934a9d467782f0d1c3fa330d6405 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Tue, 4 Oct 2022 18:10:45 +0200 Subject: [PATCH] If FAIL_ON_MISSING_CLASSES is disabled only log a summary of classes with WARN level (#210) --- .../de/thetaphi/forbiddenapis/AsmUtils.java | 19 +++++++++++++++++++ .../de/thetaphi/forbiddenapis/Checker.java | 14 ++++++++++---- .../de/thetaphi/forbiddenapis/Signatures.java | 15 +-------------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java b/src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java index 6411cf9..1d07bc3 100644 --- a/src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java +++ b/src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java @@ -23,6 +23,7 @@ import java.net.URL; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.Collection; import java.util.Locale; import java.util.Objects; import java.util.regex.Pattern; @@ -190,5 +191,23 @@ public static boolean isExceptionInAsmClassReader(RuntimeException re) { final StackTraceElement[] stack = re.getStackTrace(); return stack.length > 0 && Objects.equals(ClassReader.class.getName(), stack[0].getClassName()); } + + /** Formats a list of classes, abbreviated, with 2 spaces in front (for logging) */ + public static String formatClassesAbbreviated(Collection missingClasses) { + final StringBuilder sb = new StringBuilder(); + int count = 0; + for (String s : missingClasses) { + sb.append(count == 0 ? " " : ", ").append(s); + count++; + if (sb.length() >= 70) { + int remaining = missingClasses.size() - count; + if (remaining > 0) { + sb.append(",... (and ").append(remaining).append(" more)."); + } + break; + } + } + return sb.toString(); + } } diff --git a/src/main/java/de/thetaphi/forbiddenapis/Checker.java b/src/main/java/de/thetaphi/forbiddenapis/Checker.java index 8819e64..29a3399 100644 --- a/src/main/java/de/thetaphi/forbiddenapis/Checker.java +++ b/src/main/java/de/thetaphi/forbiddenapis/Checker.java @@ -74,6 +74,10 @@ public static enum Option { /** Cache of loaded classes: key is the binary name (dotted) */ final Map classpathClassCache = new HashMap<>(); + /** Related classes (binary name, dotted) which were not found while looking up + * class metadata [referenced (super)classes, interfaces,...] */ + final Set missingClasses = new TreeSet<>(); + final Signatures forbiddenSignatures; /** descriptors (not internal names) of all annotations that suppress */ @@ -305,10 +309,7 @@ public ClassMetadata lookupRelatedClass(String internalName, String internalName if (options.contains(Option.FAIL_ON_MISSING_CLASSES)) { throw new RelatedClassLoadingException(cnfe, origClassName); } else { - logger.warn(String.format(Locale.ENGLISH, - "Class '%s' cannot be loaded (while looking up details about referenced class '%s'). Please fix the classpath!", - type.getClassName(), origClassName - )); + missingClasses.add(type.getClassName()); return null; } } catch (IOException ioe) { @@ -464,6 +465,11 @@ public void run() throws ForbiddenApiException { errors += checkClass(c, suppressAnnotationsPattern); } + if (!missingClasses.isEmpty() ) { + logger.warn("While scanning classes to check, the following referenced classes were not found on classpath (this may miss some violations):"); + logger.warn(AsmUtils.formatClassesAbbreviated(missingClasses)); + } + final String message = String.format(Locale.ENGLISH, "Scanned %d class file(s) for forbidden API invocations (in %.2fs), %d error(s).", classesToCheck.size(), (System.currentTimeMillis() - start) / 1000.0, errors); diff --git a/src/main/java/de/thetaphi/forbiddenapis/Signatures.java b/src/main/java/de/thetaphi/forbiddenapis/Signatures.java index a98a8c1..9e9a746 100644 --- a/src/main/java/de/thetaphi/forbiddenapis/Signatures.java +++ b/src/main/java/de/thetaphi/forbiddenapis/Signatures.java @@ -232,20 +232,7 @@ private void reportMissingSignatureClasses(Set missingClasses) { return; } logger.warn("Some signatures were ignored because the following classes were not found on classpath:"); - final StringBuilder sb = new StringBuilder(); - int count = 0; - for (String s : missingClasses) { - sb.append(count == 0 ? " " : ", ").append(s); - count++; - if (sb.length() >= 70) { - int remaining = missingClasses.size() - count; - if (remaining > 0) { - sb.append(",... (and ").append(remaining).append(" more)."); - } - break; - } - } - logger.warn(sb.toString()); + logger.warn(AsmUtils.formatClassesAbbreviated(missingClasses)); } private void addBundledSignatures(String name, String jdkTargetVersion, boolean logging, Set missingClasses) throws IOException,ParseException {