2323import org .gradle .api .tasks .Optional ;
2424import org .gradle .api .tasks .OutputFile ;
2525import org .gradle .api .tasks .TaskAction ;
26+ import org .jetbrains .annotations .NotNull ;
2627import org .objectweb .asm .ClassReader ;
2728import org .objectweb .asm .ClassVisitor ;
2829import org .objectweb .asm .ModuleVisitor ;
3435import java .io .InputStream ;
3536import java .lang .module .ModuleFinder ;
3637import java .nio .charset .StandardCharsets ;
38+ import java .nio .file .FileVisitResult ;
3739import java .nio .file .Files ;
3840import java .nio .file .Path ;
41+ import java .nio .file .SimpleFileVisitor ;
42+ import java .nio .file .attribute .BasicFileAttributes ;
3943import java .security .CodeSource ;
4044import java .util .ArrayList ;
4145import java .util .Arrays ;
4751import java .util .regex .Pattern ;
4852import java .util .zip .ZipEntry ;
4953
54+ import static java .nio .file .FileVisitResult .CONTINUE ;
55+ import static java .nio .file .FileVisitResult .TERMINATE ;
56+
5057/**
5158 * This task generates a file with a class to module mapping
5259 * used to imitate modular behavior during unit tests so
@@ -249,9 +256,9 @@ private String extractModuleNameFromJar(File file, JarFile jarFile) throws IOExc
249256 /**
250257 * find the first class and module when the class path entry is a directory
251258 */
252- private void extractLocationsFromDirectory (File directory , List <Location > locations ) throws IOException {
253- String className = extractClassNameFromDirectory (directory );
254- String moduleName = extractModuleNameFromDirectory (directory );
259+ private void extractLocationsFromDirectory (File dir , List <Location > locations ) throws IOException {
260+ String className = extractClassNameFromDirectory (dir );
261+ String moduleName = extractModuleNameFromDirectory (dir );
255262
256263 if (className != null && moduleName != null ) {
257264 locations .add (new Location (moduleName , className ));
@@ -262,22 +269,22 @@ private void extractLocationsFromDirectory(File directory, List<Location> locati
262269 * look through the directory to find the first unique class that isn't
263270 * module-info.class (which may not be unique) and avoid anonymous classes
264271 */
265- private String extractClassNameFromDirectory (File directory ) throws IOException {
266- List < File > files = new ArrayList <>( List . of ( directory ));
267- while ( files . isEmpty () == false ) {
268- File find = files . removeFirst ();
269- if ( find . exists () ) {
270- if ( find . getName ().endsWith ( ".class" )
271- && find . getName () .equals ("module-info.class" ) == false
272- && find . getName ().contains ( "$" ) == false ) {
273- return find . getAbsolutePath (). substring ( directory . getAbsolutePath (). length () + 1 ) ;
274- } else if ( find . isDirectory ()) {
275- files . addAll ( Arrays . asList ( find . listFiles ())) ;
272+ private String extractClassNameFromDirectory (File dir ) throws IOException {
273+ var visitor = new SimpleFileVisitor < Path >() {
274+ String result = null ;
275+ @ Override
276+ public @ NotNull FileVisitResult visitFile ( @ NotNull Path candidate , @ NotNull BasicFileAttributes attrs ) {
277+ String name = candidate . getFileName ().toString (); // Just the part after the last dir separator
278+ if ( name . endsWith ( ".class" ) && ( name .equals ("module-info.class" ) || name . contains ( "$" )) == false ) {
279+ result = candidate . toAbsolutePath ().toString (). substring ( dir . getAbsolutePath (). length () + 1 );
280+ return TERMINATE ;
281+ } else {
282+ return CONTINUE ;
276283 }
277284 }
278-
279- }
280- return null ;
285+ };
286+ Files . walkFileTree ( dir . toPath (), visitor );
287+ return visitor . result ;
281288 }
282289
283290 /**
0 commit comments