public void detect ( final String ... packageNames ) throws IOException { final String [ ] pkgNameFilter = new String [ packageNames . length ] ; for ( int i = 0 ; i < pkgNameFilter . length ; ++ i ) { pkgNameFilter [ i ] = packageNames [ i ] . replace ( ' ' , ' ' ) ; if ( ! pkgNameFilter [ i ] . endsWith ( "/" ) ) { pkgNameFilter [ i ] = pkgNameFilter [ i ] . concat ( "/" ) ; } } final Set < File > files = new HashSet <> ( ) ; final ClassLoader loader = Thread . currentThread ( ) . getContextClassLoader ( ) ; for ( final String packageName : pkgNameFilter ) { final Enumeration < URL > resourceEnum = loader . getResources ( packageName ) ; while ( resourceEnum . hasMoreElements ( ) ) { final URL url = resourceEnum . nextElement ( ) ; if ( "file" . equals ( url . getProtocol ( ) ) ) { final File dir = toFile ( url ) ; if ( dir . isDirectory ( ) ) { files . add ( dir ) ; } else { throw new AssertionError ( "Not a recognized file URL: " + url ) ; } } else { final File jarFile = toFile ( openJarURLConnection ( url ) . getJarFileURL ( ) ) ; if ( jarFile . isFile ( ) ) { files . add ( jarFile ) ; } else { throw new AssertionError ( "Not a File: " + jarFile ) ; } } } } if ( DEBUG ) { print ( "Files to scan: %s" , files ) ; } if ( ! files . isEmpty ( ) ) { // see http://shipilev.net/blog/2016/arrays-wisdom-ancients/#_conclusion detect ( new ClassFileIterator ( files . toArray ( new File [ 0 ] ) , pkgNameFilter ) ) ; } }
Report all Java ClassFile files available on the class path within the specified packages and sub packages .