Repository: quarkusio/quarkus
Issue: Exception when directory doesn't exist with quarkus-maven-plugin

**Describe the bug**
The `quarkus-maven-plugin` fails with an exception if it's configured with a `finalName` using a directory that doesn't exist. I think this was working in previous versions, so looks like a regression.

**To Reproduce**

In your pom.xml
```
...
<plugin>
				<groupId>io.quarkus</groupId>
				<artifactId>quarkus-maven-plugin</artifactId>
				<version>1.0.0.CR2</version>
				<executions>
					<execution>
						<goals>
							<goal>build</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<finalName>${project.build.directory}/non-existing-dir/${project.build.finalName}</finalName>
				</configuration>
			</plugin>
...
```

Then `mvn clean package` will fail with an exception like this one:

```
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:1.0.0.CR2:build (default) on project server-quarkus: Failed to build a runnable JAR: Failed to augment application classes: Build failure: Build failed due to errors
[ERROR]     [error]: Build step io.quarkus.deployment.pkg.steps.JarResultBuildStep#buildRunnerJar threw an exception: java.lang.IllegalStateException: java.io.IOException: Failed to create a new filesystem for jar:file:/tmp/test/target/non-existing-dir/server-quarkus-1.0-SNAPSHOT-runner.jar
[ERROR]     at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:950)
[ERROR]     at io.quarkus.builder.BuildContext.run(BuildContext.java:415)
[ERROR]     at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
[ERROR]     at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
[ERROR]     at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535)
[ERROR]     at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1426)
[ERROR]     at java.base/java.lang.Thread.run(Thread.java:834)
[ERROR]     at org.jboss.threads.JBossThread.run(JBossThread.java:479)
[ERROR] Caused by: java.io.IOException: Failed to create a new filesystem for jar:file:/tmp/test/target/non-existing-dir/server-quarkus-1.0-SNAPSHOT-runner.jar
[ERROR]     at io.quarkus.bootstrap.util.ZipUtils.newFileSystem(ZipUtils.java:150)
[ERROR]     at io.quarkus.bootstrap.util.ZipUtils.newZip(ZipUtils.java:102)
[ERROR]     at io.quarkus.deployment.pkg.steps.JarResultBuildStep.buildThinJar(JarResultBuildStep.java:295)
[ERROR]     at io.quarkus.deployment.pkg.steps.JarResultBuildStep.buildRunnerJar(JarResultBuildStep.java:141)
[ERROR]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR]     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR]     at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR]     at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:941)
[ERROR]     ... 7 more
[ERROR] Caused by: java.nio.file.NoSuchFileException: /tmp/test/target/non-existing-dir/server-quarkus-1.0-SNAPSHOT-runner.jar
[ERROR]     at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
[ERROR]     at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
[ERROR]     at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
[ERROR]     at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219)
[ERROR]     at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:478)
[ERROR]     at java.base/java.nio.file.Files.newOutputStream(Files.java:219)
[ERROR]     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.<init>(ZipFileSystem.java:112)
[ERROR]     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:109)
[ERROR]     at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:337)
[ERROR]     at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:286)
[ERROR]     at io.quarkus.bootstrap.util.ZipUtils.newFileSystem(ZipUtils.java:143)
[ERROR]     ... 15 more
[ERROR] -> [Help 1]
[ERROR]
```


Changed files:
independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/util/ZipUtils.java
independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/util/ZipUtilsTest.java

diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/util/ZipUtils.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/util/ZipUtils.java
index 541e179aa65..d98313f6462 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/util/ZipUtils.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/util/ZipUtils.java
@@ -99,7 +99,19 @@ public static void zip(Path src, Path zipFile) throws IOException {
     }
 
     public static FileSystem newZip(Path zipFile) throws IOException {
-        return newFileSystem(toZipUri(zipFile), Files.exists(zipFile) ? Collections.emptyMap() : CREATE_ENV);
+        final Map<String, ?> env;
+        if (Files.exists(zipFile)) {
+            env = Collections.emptyMap();
+        } else {
+            env = CREATE_ENV;
+            // explicitly create any parent dirs, since the ZipFileSystem only creates a new file
+            // with "create" = "true", but doesn't create any parent dirs.
+
+            // It's OK to not check the existence of the parent dir(s) first, since the API,
+            // as per its contract doesn't throw any exception if the parent dir(s) already exist
+            Files.createDirectories(zipFile.getParent());
+        }
+        return newFileSystem(toZipUri(zipFile), env);
     }
 
     private static void copyToZip(Path srcRoot, Path srcPath, FileSystem zipfs) throws IOException {
diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/util/ZipUtilsTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/util/ZipUtilsTest.java
index 4dcb7d0878f..66440560fc8 100644
--- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/util/ZipUtilsTest.java
+++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/util/ZipUtilsTest.java
@@ -5,10 +5,15 @@
 
 import java.io.IOException;
 import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Collections;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 /**
  * Tests {@link ZipUtils}
  */
@@ -49,4 +54,59 @@ public void testCorruptZipException() throws Exception {
             Files.delete(tmpFile);
         }
     }
+
+    /**
+     * Test that the {@link ZipUtils#newZip(Path)} works as expected
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testNewZip() throws Exception {
+        final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir"));
+        final Path zipPath = Paths.get(tmpDir.toString(), "ziputilstest-" + System.currentTimeMillis() + ".jar");
+        try {
+            try (final FileSystem fs = ZipUtils.newZip(zipPath)) {
+                final Path someFileInZip = fs.getPath("hello.txt");
+                Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8));
+            }
+            // now just verify that the content was actually written out
+            try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) {
+                assertFileExistsWithContent(fs.getPath("hello.txt"), "hello");
+            }
+        } finally {
+            Files.deleteIfExists(zipPath);
+        }
+    }
+
+    /**
+     * Tests that the {@link ZipUtils#newZip(Path)} works correctly, and creates the zip file,
+     * when the parent directories of the {@link Path} passed to it are not present.
+     *
+     * @throws Exception
+     * @see <a href="https://github.com/quarkusio/quarkus/issues/5680"/>
+     */
+    @Test
+    public void testNewZipForNonExistentParentDir() throws Exception {
+        final Path tmpDir = Files.createTempDirectory(null);
+        final Path nonExistentLevel1Dir = tmpDir.resolve("non-existent-level1");
+        final Path nonExistentLevel2Dir = nonExistentLevel1Dir.resolve("non-existent-level2");
+        final Path zipPath = Paths.get(nonExistentLevel2Dir.toString(), "ziputilstest-nonexistentdirs.jar");
+        try {
+            try (final FileSystem fs = ZipUtils.newZip(zipPath)) {
+                final Path someFileInZip = fs.getPath("hello.txt");
+                Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8));
+            }
+            // now just verify that the content was actually written out
+            try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) {
+                assertFileExistsWithContent(fs.getPath("hello.txt"), "hello");
+            }
+        } finally {
+            Files.deleteIfExists(zipPath);
+        }
+    }
+
+    private static void assertFileExistsWithContent(final Path path, final String content) throws IOException {
+        final String readContent = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
+        assertEquals(content, readContent, "Unexpected content in " + path);
+    }
 }