diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/ClassScanner.java b/hutool-core/src/main/java/cn/hutool/core/reflect/ClassScanner.java index f1e5aa5c3..5070bcd8e 100755 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/ClassScanner.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/ClassScanner.java @@ -72,6 +72,14 @@ public class ClassScanner implements Serializable { * 扫描结果集 */ private final Set> classes = new HashSet<>(); + /** + * 忽略loadClass时的错误 + */ + private boolean ignoreLoadError = false; + /** + * 获取加载错误的类名列表 + */ + private final Set classesOfLoadError = new HashSet<>(); /** * 扫描指定包路径下所有包含指定注解的类,包括其他加载的jar或者类 @@ -194,7 +202,7 @@ public class ClassScanner implements Serializable { /** * 构造,默认UTF-8编码 * - * @param packageName 包名,所有包传入""或者null + * @param packageName 包名,所有包传入""或者null * @param classPredicate 过滤器,无需传入null */ public ClassScanner(final String packageName, final Predicate> classPredicate) { @@ -204,9 +212,9 @@ public class ClassScanner implements Serializable { /** * 构造 * - * @param packageName 包名,所有包传入""或者null + * @param packageName 包名,所有包传入""或者null * @param classPredicate 过滤器,无需传入null - * @param charset 编码 + * @param charset 编码 */ public ClassScanner(String packageName, final Predicate> classPredicate, final Charset charset) { packageName = StrUtil.emptyIfNull(packageName); @@ -236,6 +244,10 @@ public class ClassScanner implements Serializable { * @since 5.7.5 */ public Set> scan(final boolean forceScanJavaClassPaths) { + //多次扫描时,清理上次扫描历史 + this.classes.clear(); + this.classesOfLoadError.clear(); + for (final URL url : ResourceUtil.getResourceUrlIter(this.packagePath)) { switch (url.getProtocol()) { case "file": @@ -255,6 +267,24 @@ public class ClassScanner implements Serializable { return Collections.unmodifiableSet(this.classes); } + /** + * 忽略加载错误扫描后,可以获得之前扫描时加载错误的类名字集合 + * + * @return 加载错误的类名字集合 + */ + public Set getClassesOfLoadError() { + return Collections.unmodifiableSet(this.classesOfLoadError); + } + + /** + * 设置是否忽略所有错误 + * + * @param ignoreLoadError 是否忽略错误 + */ + public void setIgnoreLoadError(final boolean ignoreLoadError) { + this.ignoreLoadError = ignoreLoadError; + } + /** * 设置是否在扫描到类时初始化类 * @@ -363,7 +393,13 @@ public class ClassScanner implements Serializable { } catch (final UnsupportedClassVersionError e) { // 版本导致的不兼容的类,跳过 } catch (final Exception e) { - throw new RuntimeException(e); + classesOfLoadError.add(className); + } catch (final Throwable e){ + if(false == this.ignoreLoadError) { + throw new RuntimeException(e); + }else{ + classesOfLoadError.add(className); + } } return clazz; } diff --git a/hutool-core/src/test/java/cn/hutool/core/reflect/ClassScanerTest.java b/hutool-core/src/test/java/cn/hutool/core/reflect/ClassScannerTest.java similarity index 64% rename from hutool-core/src/test/java/cn/hutool/core/reflect/ClassScanerTest.java rename to hutool-core/src/test/java/cn/hutool/core/reflect/ClassScannerTest.java index 8a2b9cd98..ed1d8c601 100644 --- a/hutool-core/src/test/java/cn/hutool/core/reflect/ClassScanerTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/reflect/ClassScannerTest.java @@ -1,13 +1,12 @@ package cn.hutool.core.reflect; import cn.hutool.core.lang.Console; -import cn.hutool.core.reflect.ClassScanner; import org.junit.Ignore; import org.junit.Test; import java.util.Set; -public class ClassScanerTest { +public class ClassScannerTest { @Test @Ignore @@ -21,7 +20,7 @@ public class ClassScanerTest { @Test @Ignore - public void scanPackageBySuperTest(){ + public void scanPackageBySuperTest() { // 扫描包,如果在classpath下找到,就不扫描JDK的jar了 final Set> classes = ClassScanner.scanPackageBySuper(null, Iterable.class); Console.log(classes.size()); @@ -29,9 +28,19 @@ public class ClassScanerTest { @Test @Ignore - public void scanAllPackageBySuperTest(){ + public void scanAllPackageBySuperTest() { // 扫描包,如果在classpath下找到,就不扫描JDK的jar了 final Set> classes = ClassScanner.scanAllPackageBySuper(null, Iterable.class); Console.log(classes.size()); } + + @Test + @Ignore + public void scanAllPackageIgnoreLoadErrorTest() { + final ClassScanner classScanner = new ClassScanner(null, null); + classScanner.setIgnoreLoadError(true); + final Set> classes = classScanner.scan(false); + Console.log(classes.size()); + Console.log(classScanner.getClassesOfLoadError()); + } }