Repository: quarkusio/quarkus
Issue: java.nio.file.NoSuchFileException thrown for string delimited with ':' (path) supplied by Gradle when multiple source path used (e.g. Kotlin of generated sourceSet)

**Describe the bug**
java.nio.file.NoSuchFileException thrown for string delimited with ':' (path) supplied by Gradle when multiple source path used (e.g. Kotlin of generated sourceSet).

**To Reproduce**
Steps to reproduce the behavior:
1.  `git clone -b quarkus-spring-mvc git@github.com:soberich/marvel.git`
2.  `./gradlew -x test app:quarkusDev`

**stacktrace**
```console
Exception in thread "main" java.nio.file.NoSuchFileException: /Users/Projects/marvel-github/spi/build/classes/java/main:/Users/Projects/marvel-github/spi/build/classes/kotlin/main:/Users/Projects/marvel-github/spi/build/tmp/kapt3/classes/main
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
        at sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
        at sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:144)
        at java.nio.file.Files.readAttributes(Files.java:1737)
        at java.nio.file.FileTreeWalker.getAttributes(FileTreeWalker.java:219)
        at java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:276)
        at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:322)
        at java.nio.file.FileTreeIterator.<init>(FileTreeIterator.java:72)
        at java.nio.file.Files.walk(Files.java:3574)
        at java.nio.file.Files.walk(Files.java:3625)
        at io.quarkus.dev.RuntimeUpdatesProcessor.checkForClassFilesChangesInModule(RuntimeUpdatesProcessor.java:196)
```


Changed files:
core/devmode/src/main/java/io/quarkus/dev/RuntimeUpdatesProcessor.java

diff --git a/core/devmode/src/main/java/io/quarkus/dev/RuntimeUpdatesProcessor.java b/core/devmode/src/main/java/io/quarkus/dev/RuntimeUpdatesProcessor.java
index 65280e047e2..d2284fd27ad 100644
--- a/core/devmode/src/main/java/io/quarkus/dev/RuntimeUpdatesProcessor.java
+++ b/core/devmode/src/main/java/io/quarkus/dev/RuntimeUpdatesProcessor.java
@@ -192,38 +192,40 @@ private boolean checkForClassFilesChangesInModule(DevModeContext.ModuleInfo modu
         }
 
         try {
-            final Path moduleClassesPath = Paths.get(module.getClassesPath());
-            try (final Stream<Path> classesStream = Files.walk(moduleClassesPath)) {
-                final Set<Path> classFilePaths = classesStream
-                        .parallel()
-                        .filter(path -> path.toString().endsWith(CLASS_EXTENSION))
-                        .collect(Collectors.toSet());
-
-                for (Path classFilePath : classFilePaths) {
-                    final Path sourceFilePath = retrieveSourceFilePathForClassFile(classFilePath, moduleChangedSourceFiles,
-                            module);
-                    final long classFileModificationTime = Files.getLastModifiedTime(classFilePath).toMillis();
-                    if (sourceFilePath != null) {
-                        if (Files.notExists(sourceFilePath)) {
-                            // Source file has been deleted. Delete class and restart
-                            Files.deleteIfExists(classFilePath);
-                            classFilePathToSourceFilePath.remove(classFilePath);
-                            hasChanges = true;
-                        } else {
-                            classFilePathToSourceFilePath.put(classFilePath, sourceFilePath);
-                            if (classFileModificationTime > lastChange) {
-                                // At least one class was recently modified. Restart.
-                                hasChanges = true;
-                            } else if (moduleChangedSourceFiles.contains(sourceFilePath)) {
-                                // Source file has been modified, we delete the .class files as they are going to
-                                //be recompiled anyway, this allows for simple cleanup of inner classes
+            for (String folder : module.getClassesPath().split(File.pathSeparator)) {
+                final Path moduleClassesPath = Paths.get(folder);
+                try (final Stream<Path> classesStream = Files.walk(moduleClassesPath)) {
+                    final Set<Path> classFilePaths = classesStream
+                            .parallel()
+                            .filter(path -> path.toString().endsWith(CLASS_EXTENSION))
+                            .collect(Collectors.toSet());
+
+                    for (Path classFilePath : classFilePaths) {
+                        final Path sourceFilePath = retrieveSourceFilePathForClassFile(classFilePath, moduleChangedSourceFiles,
+                                module);
+                        final long classFileModificationTime = Files.getLastModifiedTime(classFilePath).toMillis();
+                        if (sourceFilePath != null) {
+                            if (!sourceFilePath.toFile().exists()) {
+                                // Source file has been deleted. Delete class and restart
                                 Files.deleteIfExists(classFilePath);
                                 classFilePathToSourceFilePath.remove(classFilePath);
                                 hasChanges = true;
+                            } else {
+                                classFilePathToSourceFilePath.put(classFilePath, sourceFilePath);
+                                if (classFileModificationTime > lastChange) {
+                                    // At least one class was recently modified. Restart.
+                                    hasChanges = true;
+                                } else if (moduleChangedSourceFiles.contains(sourceFilePath)) {
+                                    // Source file has been modified, we delete the .class files as they are going to
+                                    //be recompiled anyway, this allows for simple cleanup of inner classes
+                                    Files.deleteIfExists(classFilePath);
+                                    classFilePathToSourceFilePath.remove(classFilePath);
+                                    hasChanges = true;
+                                }
                             }
+                        } else if (classFileModificationTime > lastChange) {
+                            hasChanges = true;
                         }
-                    } else if (classFileModificationTime > lastChange) {
-                        hasChanges = true;
                     }
                 }
             }
@@ -249,7 +251,7 @@ private Optional<String> matchingHandledExtension(Path p) {
 
     private String getFileExtension(File file) {
         String name = file.getName();
-        int lastIndexOf = name.lastIndexOf(".");
+        int lastIndexOf = name.lastIndexOf('.');
         if (lastIndexOf == -1) {
             return ""; // empty extension
         }
@@ -273,7 +275,7 @@ private Set<String> checkForFileChange() {
 
             for (String path : watchedFilePaths.keySet()) {
                 Path file = root.resolve(path);
-                if (Files.exists(file)) {
+                if (file.toFile().exists()) {
                     try {
                         long value = Files.getLastModifiedTime(file).toMillis();
                         Long existing = watchedFileTimestamps.get(file);
@@ -332,7 +334,7 @@ public RuntimeUpdatesProcessor setWatchedFilePaths(Map<String, Boolean> watchedF
             Path root = Paths.get(rootPath);
             for (String path : watchedFilePaths.keySet()) {
                 Path config = root.resolve(path);
-                if (Files.exists(config)) {
+                if (config.toFile().exists()) {
                     try {
                         watchedFileTimestamps.put(config, Files.getLastModifiedTime(config).toMillis());
                     } catch (IOException e) {