From 818f090d8e89d3ce79bdeb63c9ebf5dab4614a33 Mon Sep 17 00:00:00 2001 From: Kristian Kraljic Date: Tue, 29 Jul 2025 15:56:05 +0200 Subject: [PATCH] fix: make ClassPathScanner ignore abstract classes Currently ClassPathScanner is returning public abstract classes, which fail to initialize, e.g. when trying deploying NeonBeeDeployable. This change fixes this by limiting ClassPathScanner for classes that are public and non-abstract. --- .../scanner/AnnotationClassVisitor.java | 3 ++- .../scanner/AnnotatedClassTemplate.java | 20 ++++++++++++++++++- .../scanner/ClassPathScannerTest.java | 11 +++++++--- .../scanner/AnnotatedClass.java.template | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/neonbee/internal/scanner/AnnotationClassVisitor.java b/src/main/java/io/neonbee/internal/scanner/AnnotationClassVisitor.java index b6d76507f..cd81adaa4 100644 --- a/src/main/java/io/neonbee/internal/scanner/AnnotationClassVisitor.java +++ b/src/main/java/io/neonbee/internal/scanner/AnnotationClassVisitor.java @@ -70,7 +70,8 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (includeTypes && ((this.access & Opcodes.ACC_PUBLIC) != 0) && annotationClassDescriptor.equals(desc)) { + if (includeTypes && ((this.access & Opcodes.ACC_PUBLIC) != 0) && (this.access & Opcodes.ACC_ABSTRACT) == 0 + && annotationClassDescriptor.equals(desc)) { classNames.add(className); } diff --git a/src/test/java/io/neonbee/internal/scanner/AnnotatedClassTemplate.java b/src/test/java/io/neonbee/internal/scanner/AnnotatedClassTemplate.java index 1de58fc83..7f3593445 100644 --- a/src/test/java/io/neonbee/internal/scanner/AnnotatedClassTemplate.java +++ b/src/test/java/io/neonbee/internal/scanner/AnnotatedClassTemplate.java @@ -15,6 +15,8 @@ public class AnnotatedClassTemplate implements ClassTemplate { private static final String PLACEHOLDER_IMPORTS = ""; + private static final String PLACEHOLDER_VISIBILITY = ""; + private static final String PLACEHOLDER_CLASS_NAME = ""; private static final String PLACEHOLDER_TYPE_ANNOTATION = ""; @@ -23,6 +25,8 @@ public class AnnotatedClassTemplate implements ClassTemplate { private static final String PLACEHOLDER_METHOD_ANNOTATION = ""; + private final String visibility; + private final String packageName; private final String simpleClassName; @@ -55,6 +59,19 @@ public AnnotatedClassTemplate(String simpleClassName) throws IOException { * @throws IOException Template file could not be read */ public AnnotatedClassTemplate(String simpleClassName, String packageName) throws IOException { + this(null, simpleClassName, packageName); + } + + /** + * Creates a dummy annotated class + * + * @param visibility The visibility of the class (public, private, protected, default) + * @param simpleClassName The simple class name of the new class + * @param packageName The package name of the class. Pass null for default package + * @throws IOException Template file could not be read + */ + public AnnotatedClassTemplate(String visibility, String simpleClassName, String packageName) throws IOException { + this.visibility = visibility != null ? visibility : "public"; this.packageName = packageName; this.simpleClassName = simpleClassName; this.template = TEST_RESOURCES.getRelated("AnnotatedClass.java.template").toString(); @@ -98,7 +115,8 @@ public String reifyTemplate() { packageNameReplacement = "package " + packageName + ";"; } - return template.replace(PLACEHOLDER_CLASS_NAME, simpleClassName) + return template.replace(PLACEHOLDER_VISIBILITY, visibility) + .replace(PLACEHOLDER_CLASS_NAME, simpleClassName) .replace(PLACEHOLDER_IMPORTS, buildImportString()).replace(PLACEHOLDER_PACKAGE, packageNameReplacement) .replace(PLACEHOLDER_TYPE_ANNOTATION, Optional.ofNullable(typeAnnotation).orElse("")) .replace(PLACEHOLDER_FIELD_ANNOTATION, Optional.ofNullable(fieldAnnotation).orElse("")) diff --git a/src/test/java/io/neonbee/internal/scanner/ClassPathScannerTest.java b/src/test/java/io/neonbee/internal/scanner/ClassPathScannerTest.java index 09bbbcd1a..25cde5ca5 100644 --- a/src/test/java/io/neonbee/internal/scanner/ClassPathScannerTest.java +++ b/src/test/java/io/neonbee/internal/scanner/ClassPathScannerTest.java @@ -126,6 +126,9 @@ void scanWithPredicateJarFile(Vertx vertx, VertxTestContext testContext) throws void scanForAnnotation(Vertx vertx, VertxTestContext testContext) throws IOException { BasicJar jarWithTypeAnnotatedClass = new AnnotatedClassTemplate("Hodor", "type").setTypeAnnotation("@Deprecated").asJar(); + BasicJar jarWithAbstractTypeAnnotatedClass = + new AnnotatedClassTemplate("public abstract", "AbstractHodor", "type").setTypeAnnotation("@Deprecated") + .asJar(); BasicJar jarWithFieldAnnotatedClass = new AnnotatedClassTemplate("Hodor", "field").setFieldAnnotation("@Deprecated").asJar(); BasicJar jarWithMethodAnnotatedClass = @@ -135,8 +138,11 @@ void scanForAnnotation(Vertx vertx, VertxTestContext testContext) throws IOExcep .setMethodAnnotation("@Transient").setImports(List.of("java.beans.Transient")).asJar(); URL[] urlc = Stream - .of(jarWithTypeAnnotatedClass.writeToTempURL(), jarWithFieldAnnotatedClass.writeToTempURL(), - jarWithMethodAnnotatedClass.writeToTempURL(), jarWithMethodAnnotatedClass2.writeToTempURL()) + .of(jarWithTypeAnnotatedClass.writeToTempURL(), + jarWithAbstractTypeAnnotatedClass.writeToTempURL(), + jarWithFieldAnnotatedClass.writeToTempURL(), + jarWithMethodAnnotatedClass.writeToTempURL(), + jarWithMethodAnnotatedClass2.writeToTempURL()) .flatMap(Stream::of).toArray(URL[]::new); ClassPathScanner cps = new ClassPathScanner(new URLClassLoader(urlc, null)); @@ -144,7 +150,6 @@ void scanForAnnotation(Vertx vertx, VertxTestContext testContext) throws IOExcep futureContainsExactly(testContext, annotationsScanned, cps.scanForAnnotation(vertx, Deprecated.class, TYPE), "type.Hodor"); - futureContainsExactly(testContext, annotationsScanned, cps.scanForAnnotation(vertx, Deprecated.class, FIELD), "field.Hodor"); futureContainsExactly(testContext, annotationsScanned, cps.scanForAnnotation(vertx, Deprecated.class, METHOD), diff --git a/src/test/resources/io/neonbee/internal/scanner/AnnotatedClass.java.template b/src/test/resources/io/neonbee/internal/scanner/AnnotatedClass.java.template index ee6521a6f..e4ba3cc9c 100644 --- a/src/test/resources/io/neonbee/internal/scanner/AnnotatedClass.java.template +++ b/src/test/resources/io/neonbee/internal/scanner/AnnotatedClass.java.template @@ -3,7 +3,7 @@ -public class { + class { private String hodor = "hodor";