Repository: quarkusio/quarkus
Issue: Liquibase still detects multiple changelogs despite upgrade to 1.4.1

**Describe the bug**
Copied from previous ticket #8400 :
During startup of quarkus dev mode, Liquibase tries to parse the configured (yaml) file containing the changeLog, this fails due to 2 such files being found in the classpath. This error does not occur in normal mode (running the runner jar).

**Expected behavior**
Liquibase only finds one changeLog file and parses it.

**Actual behavior**
```
File: Found 2 files that match db/changeLog.xml
        at io.quarkus.liquibase.runtime.LiquibaseRecorder.doStartActions(LiquibaseRecorder.java:82)
        at io.quarkus.deployment.steps.LiquibaseProcessor$configureRuntimeProperties31.deploy_0(LiquibaseProcessor$configureRuntimeProperties31.zig:98)
        at io.quarkus.deployment.steps.LiquibaseProcessor$configureRuntimeProperties31.deploy(LiquibaseProcessor$configureRuntimeProperties31.zig:36)
        at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:182)
        at io.quarkus.runtime.Application.start(Application.java:89)
        at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:90)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:61)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:106)
        at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:99)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: liquibase.exception.ChangeLogParseException: Error Reading Migration File: Found 2 files that match db/changeLog.xml
        at liquibase.parser.core.xml.XMLChangeLogSAXParser.parseToNode(XMLChangeLogSAXParser.java:118)
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:15)
        at liquibase.Liquibase.getDatabaseChangeLog(Liquibase.java:217)
        at liquibase.Liquibase.validate(Liquibase.java:1559)
        at io.quarkus.liquibase.runtime.LiquibaseRecorder.validate(LiquibaseRecorder.java:124)
        at io.quarkus.liquibase.runtime.LiquibaseRecorder.doStartActions(LiquibaseRecorder.java:66)
        ... 15 more
Caused by: java.io.IOException: Found 2 files that match db/changeLog.xml
        at liquibase.util.StreamUtil.singleInputStream(StreamUtil.java:206)
        at liquibase.parser.core.xml.XMLChangeLogSAXParser.parseToNode(XMLChangeLogSAXParser.java:71)
        ... 20 more
```

**To Reproduce**
Steps to reproduce the behavior:
1.  clone https://github.com/gastaldi/liquibase-gradle-bug
2. change gradle.properties from 999-snapshot to 1.4.1.Final
3. ./gradlew quarkusDev

**Configuration**
```properties
# Add your application.properties here, if applicable.
#Gradle properties
#Mon Apr 06 13:51:25 GMT 2020
quarkusPluginVersion=1.4.1.Final
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformGroupId=io.quarkus
quarkusPlatformVersion=1.4.1.Final

#application.properties
quarkus.liquibase.change-log=db/changeLog.xml
quarkus.liquibase.migrate-at-start=true
quarkus.liquibase.validate-on-migrate=true
quarkus.datasource.db-kind=h2
quarkus.datasource.jdbc.url=jdbc:h2:mem:test
quarkus.datasource.jdbc.max-size=8
quarkus.datasource.jdbc.min-size=2
```

**Screenshots**
(If applicable, add screenshots to help explain your problem.)

**Environment (please complete the following information):**
 - Output of `uname -a` or `ver`: `Darwin kaluza.broadband 19.0.0 Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64 x86_64`
 - Output of `java -version`: `openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment GraalVM CE 19.3.1 (build 11.0.6+9-jvmci-19.3-b07)
OpenJDK 64-Bit Server VM GraalVM CE 19.3.1 (build 11.0.6+9-jvmci-19.3-b07, mixed mode, sharing)`
 - GraalVM version (if different from Java): 
 - Quarkus version or git rev: 1.4.1.Final
 - Build tool (ie. output of `mvnw --version` or `gradlew --version`): 
```
------------------------------------------------------------
Gradle 6.3
------------------------------------------------------------

Build time:   2020-03-24 19:52:07 UTC
Revision:     bacd40b727b0130eeac8855ae3f9fd9a0b207c60

Kotlin:       1.3.70
Groovy:       2.5.10
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          11.0.6 (Oracle Corporation 11.0.6+9-jvmci-19.3-b07)
OS:           Mac OS X 10.15.1 x86_64
```

**Additional context**
(Add any other context about the problem here.)


Changed files:
devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java
core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java
core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java
core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java

diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java
index b391fd6b164..fbdbb315a04 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java
@@ -193,6 +193,7 @@ public static class ModuleInfo implements Serializable {
         private final Set<String> sourcePaths;
         private final String classesPath;
         private final String resourcePath;
+        private final String resourcesOutputPath;
 
         public ModuleInfo(
                 String name,
@@ -200,11 +201,22 @@ public ModuleInfo(
                 Set<String> sourcePaths,
                 String classesPath,
                 String resourcePath) {
+            this(name, projectDirectory, sourcePaths, classesPath, resourcePath, classesPath);
+        }
+
+        public ModuleInfo(
+                String name,
+                String projectDirectory,
+                Set<String> sourcePaths,
+                String classesPath,
+                String resourcePath,
+                String resourceOutputPath) {
             this.name = name;
             this.projectDirectory = projectDirectory;
             this.sourcePaths = sourcePaths == null ? new HashSet<>() : new HashSet<>(sourcePaths);
             this.classesPath = classesPath;
             this.resourcePath = resourcePath;
+            this.resourcesOutputPath = resourceOutputPath;
         }
 
         public String getName() {
@@ -230,6 +242,10 @@ public String getClassesPath() {
         public String getResourcePath() {
             return resourcePath;
         }
+
+        public String getResourcesOutputPath() {
+            return resourcesOutputPath;
+        }
     }
 
     public boolean isEnablePreview() {
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java
index bd012f6f83a..c35479ee3a0 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java
@@ -103,7 +103,10 @@ public void start() throws Exception {
                 if (i.getClassesPath() != null) {
                     Path classesPath = Paths.get(i.getClassesPath());
                     bootstrapBuilder.addAdditionalApplicationArchive(new AdditionalDependency(classesPath, true, false));
-
+                }
+                if (i.getResourcesOutputPath() != null && !i.getResourcesOutputPath().equals(i.getClassesPath())) {
+                    Path resourceOutputPath = Paths.get(i.getResourcesOutputPath());
+                    bootstrapBuilder.addAdditionalApplicationArchive(new AdditionalDependency(resourceOutputPath, true, false));
                 }
             }
 
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java
index d56d4cd767f..6f3c4dba583 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java
@@ -302,8 +302,10 @@ Set<String> checkForFileChange() {
                     m -> Collections.newSetFromMap(new ConcurrentHashMap<>()));
             boolean doCopy = true;
             String rootPath = module.getResourcePath();
+            String outputPath = module.getResourcesOutputPath();
             if (rootPath == null) {
                 rootPath = module.getClassesPath();
+                outputPath = rootPath;
                 doCopy = false;
             }
             if (rootPath == null) {
@@ -313,7 +315,7 @@ Set<String> checkForFileChange() {
             if (!Files.exists(root) || !Files.isReadable(root)) {
                 continue;
             }
-            Path classesDir = Paths.get(module.getClassesPath());
+            Path outputDir = Paths.get(outputPath);
             //copy all modified non hot deployment files over
             if (doCopy) {
                 try {
@@ -323,7 +325,7 @@ Set<String> checkForFileChange() {
                         walk.forEach(path -> {
                             try {
                                 Path relative = root.relativize(path);
-                                Path target = classesDir.resolve(relative);
+                                Path target = outputDir.resolve(relative);
                                 seen.remove(target);
                                 if (!watchedFileTimestamps.containsKey(path)) {
                                     moduleResources.add(target);
@@ -366,7 +368,7 @@ Set<String> checkForFileChange() {
                             ret.add(path);
                             log.infof("File change detected: %s", file);
                             if (doCopy && !Files.isDirectory(file)) {
-                                Path target = classesDir.resolve(path);
+                                Path target = outputDir.resolve(path);
                                 byte[] data = Files.readAllBytes(file);
                                 try (FileOutputStream out = new FileOutputStream(target.toFile())) {
                                     out.write(data);
@@ -379,7 +381,7 @@ Set<String> checkForFileChange() {
                     }
                 } else {
                     watchedFileTimestamps.put(file, 0L);
-                    Path target = classesDir.resolve(path);
+                    Path target = outputDir.resolve(path);
                     try {
                         FileUtil.deleteDirectory(target);
                     } catch (IOException e) {
diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java
index e0a821c223b..be20f6db36c 100644
--- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java
+++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java
@@ -13,6 +13,7 @@
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -259,14 +260,6 @@ public void startDev() {
             wiringClassesDirectory.mkdirs();
             addToClassPaths(classPathManifest, context, wiringClassesDirectory);
 
-            StringBuilder resources = new StringBuilder();
-            for (File file : extension.resourcesDir()) {
-                if (resources.length() > 0) {
-                    resources.append(File.pathSeparator);
-                }
-                resources.append(file.getAbsolutePath());
-            }
-
             final Set<AppArtifactKey> projectDependencies = new HashSet<>();
             addSelfWithLocalDeps(project, context, new HashSet<>(), projectDependencies);
 
@@ -390,12 +383,18 @@ private void addLocalProject(Project project, DevModeContext context, Set<AppArt
         }
         String resourcePaths = mainSourceSet.getResources().getSourceDirectories().getSingleFile().getAbsolutePath(); //TODO: multiple resource directories
 
+        final String classesDir = QuarkusGradleUtils.getClassesDir(mainSourceSet, project.getBuildDir());
+        final String resourcesOutputPath = Files.exists(Paths.get(resourcePaths))
+                ? mainSourceSet.getOutput().getResourcesDir().getAbsolutePath()
+                : classesDir;
+
         DevModeContext.ModuleInfo wsModuleInfo = new DevModeContext.ModuleInfo(
                 project.getName(),
                 project.getProjectDir().getAbsolutePath(),
                 sourcePaths,
-                QuarkusGradleUtils.getClassesDir(mainSourceSet, project.getBuildDir()),
-                resourcePaths);
+                classesDir,
+                resourcePaths,
+                resourcesOutputPath);
 
         context.getModules().add(wsModuleInfo);