2727import java .util .Map ;
2828import java .util .Set ;
2929import java .util .function .Predicate ;
30+ import java .util .jar .Attributes ;
3031import java .util .jar .Manifest ;
3132import java .util .regex .Pattern ;
3233import java .util .stream .Stream ;
@@ -70,6 +71,8 @@ public class ClassPathScanner {
7071 */
7172 public static final Pattern SEPARATOR_PATTERN = Pattern .compile (";" );
7273
74+ private static final String NEONBEE_MANIFEST_PREFIX = "NeonBee-" ;
75+
7376 private final ClassLoader classLoader ;
7477
7578 /**
@@ -195,14 +198,15 @@ public Future<List<String>> scanForAnnotation(Vertx vertx,
195198 ElementType ... elementTypes ) {
196199
197200 Future <List <String >> classesFromDirectories = scanWithPredicate (vertx , ClassPathScanner ::isClassFile );
198- Future <List <String >> classesFromJars = scanJarFilesWithPredicate (vertx , ClassPathScanner ::isClassFile )
199- .map (uris -> {
200- List <String > result = new ArrayList <>(uris .size ());
201- for (URI uri : uris ) {
202- result .add (JarHelper .extractFilePath (uri ));
203- }
204- return result ;
205- });
201+ Future <List <String >> classesFromJars =
202+ scanJarFilesWithPredicate (vertx , ClassPathScanner ::isClassFile , ClassPathScanner ::isNeonBeeJar )
203+ .map (uris -> {
204+ List <String > result = new ArrayList <>(uris .size ());
205+ for (URI uri : uris ) {
206+ result .add (JarHelper .extractFilePath (uri ));
207+ }
208+ return result ;
209+ });
206210
207211 return Future .all (classesFromDirectories , classesFromJars ).compose (v -> vertx .executeBlocking (() -> {
208212 List <AnnotationClassVisitor > classVisitors = new ArrayList <>(annotationClasses .size ());
@@ -282,12 +286,16 @@ public Future<List<String>> scanWithPredicate(Vertx vertx, Predicate<String> pre
282286 * @return a future to a list of URIs representing the files which matches the given predicate
283287 */
284288 public Future <List <URI >> scanJarFilesWithPredicate (Vertx vertx , Predicate <String > predicate ) {
289+ return scanJarFilesWithPredicate (vertx , predicate , url -> true );
290+ }
291+
292+ private Future <List <URI >> scanJarFilesWithPredicate (Vertx vertx , Predicate <String > predicate ,
293+ Predicate <URL > jarFilter ) {
285294 return vertx .executeBlocking (() -> {
286295 List <URI > resources = new ArrayList <>();
287296 for (URL manifestResource : getManifestResourceURLs ()) {
288297 URI uri = manifestResource .toURI ();
289- // filter for manifest files inside of jar files
290- if ("jar" .equals (uri .getScheme ())) {
298+ if ("jar" .equals (uri .getScheme ()) && jarFilter .test (manifestResource )) {
291299 try (FileSystem fileSystem = FileSystems .newFileSystem (uri , Map .of ())) {
292300 Path rootPath = fileSystem .getPath ("/" );
293301 scanDirectoryWithPredicateRecursive (rootPath , predicate )
@@ -299,6 +307,21 @@ public Future<List<URI>> scanJarFilesWithPredicate(Vertx vertx, Predicate<String
299307 });
300308 }
301309
310+ @ SuppressWarnings ("PMD.EmptyCatchBlock" )
311+ private static boolean isNeonBeeJar (URL manifestUrl ) {
312+ try (InputStream is = manifestUrl .openStream ()) {
313+ Manifest manifest = new Manifest (is );
314+ Attributes attributes = manifest .getMainAttributes ();
315+ for (Object key : attributes .keySet ()) {
316+ if (key .toString ().startsWith (NEONBEE_MANIFEST_PREFIX )) {
317+ return true ;
318+ }
319+ }
320+ } catch (IOException e ) { // NOPMD
321+ }
322+ return false ;
323+ }
324+
302325 /**
303326 * Blocking method to get all resource URLs from the MANIFEST.MF file(s) on the class loader
304327 *
0 commit comments