Repository: quarkusio/quarkus
Issue: QuarkusMainTest intercepts spurious strings

### Describe the bug

The `QuarkusMainTest`s are spuriously intercepting output coming from different sources.

### Expected behavior

The `QuarkusMainTest`s report back only the output from the specific launched `Process`.

### Actual behavior

_No response_

### How to Reproduce?

I started reducing the error down to a test in this codebase.

In `io.quarkus.it.picocli.PicocliTest` add the following test:

```java
    @Test
    public void testLogCapturing(QuarkusMainLauncher launcher) {
        org.jboss.logging.Logger.getLogger("test").error("error");
        LaunchResult result = launcher.launch("with-method-sub-command", "hello", "-n", "World!");
        assertThat(result.exitCode()).isZero();
        assertThat(result.getOutput()).isEqualTo("Hello World!");
    }
```

and the test will fail with an error similar to:

```bash
[ERROR] Failures: 
[ERROR]   PicocliTest.testLogCapturing:43 
expected: "Hello World!"
 but was: "2021-12-16 19:28:23,647 ERROR [test] (main) error
Hello World!"
[INFO] 
[ERROR] Tests run: 11, Failures: 1, Errors: 0, Skipped: 0
```

The expectation is that the test should pass.

### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

_No response_

### GraalVM version (if different from Java)

_No response_

### Quarkus version or git rev

`main`

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

_No response_

### Additional information

_No response_

Changed files:
test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java
core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java
integration-tests/picocli-native/src/test/java/io/quarkus/it/picocli/PicocliTest.java

diff --git a/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java b/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java
index 8e12135244a..72aef382f78 100644
--- a/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java
+++ b/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java
@@ -51,6 +51,9 @@ public abstract class QuarkusConsole {
     public final static PrintStream ORIGINAL_OUT = System.out;
     public final static PrintStream ORIGINAL_ERR = System.err;
 
+    public static PrintStream REDIRECT_OUT = null;
+    public static PrintStream REDIRECT_ERR = null;
+
     public synchronized static void installRedirects() {
         if (redirectsInstalled) {
             return;
@@ -60,8 +63,31 @@ public synchronized static void installRedirects() {
         //force console init
         //otherwise you can get a stack overflow as it sees the redirected output
         QuarkusConsole.INSTANCE.isInputSupported();
-        System.setOut(new RedirectPrintStream(false));
-        System.setErr(new RedirectPrintStream(true));
+        REDIRECT_OUT = new RedirectPrintStream(false);
+        REDIRECT_ERR = new RedirectPrintStream(true);
+        System.setOut(REDIRECT_OUT);
+        System.setErr(REDIRECT_ERR);
+    }
+
+    public synchronized static void uninstallRedirects() {
+        if (!redirectsInstalled) {
+            return;
+        }
+
+        if (REDIRECT_OUT != null) {
+            REDIRECT_OUT.flush();
+            REDIRECT_OUT.close();
+            REDIRECT_OUT = null;
+        }
+        if (REDIRECT_ERR != null) {
+            REDIRECT_ERR.flush();
+            REDIRECT_ERR.close();
+            REDIRECT_ERR = null;
+        }
+        System.setOut(ORIGINAL_OUT);
+        System.setErr(ORIGINAL_ERR);
+
+        redirectsInstalled = false;
     }
 
     public static boolean hasColorSupport() {
diff --git a/integration-tests/picocli-native/src/test/java/io/quarkus/it/picocli/PicocliTest.java b/integration-tests/picocli-native/src/test/java/io/quarkus/it/picocli/PicocliTest.java
index 43a97fc52c6..1c69b4baae3 100644
--- a/integration-tests/picocli-native/src/test/java/io/quarkus/it/picocli/PicocliTest.java
+++ b/integration-tests/picocli-native/src/test/java/io/quarkus/it/picocli/PicocliTest.java
@@ -35,6 +35,14 @@ public void testMethodSubCommand(QuarkusMainLauncher launcher) {
         assertThat(result.getOutput()).isEqualTo("Goodbye Test?");
     }
 
+    @Test
+    public void testLogCapturing(QuarkusMainLauncher launcher) {
+        org.jboss.logging.Logger.getLogger("test").error("error");
+        LaunchResult result = launcher.launch("with-method-sub-command", "hello", "-n", "World!");
+        assertThat(result.exitCode()).isZero();
+        assertThat(result.getOutput()).isEqualTo("Hello World!");
+    }
+
     @Test
     @Launch({ "command-used-as-parent", "-p", "testValue", "child" })
     public void testParentCommand(LaunchResult result) {
diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java
index d7609c833f1..1109eb78fdd 100644
--- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java
+++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java
@@ -93,7 +93,6 @@ private void ensurePrepared(ExtensionContext extensionContext, Class<? extends Q
     private LaunchResult doLaunch(ExtensionContext context, Class<? extends QuarkusTestProfile> selectedProfile,
             String[] arguments) throws Exception {
         ensurePrepared(context, selectedProfile);
-        QuarkusConsole.installRedirects();
         LogCapturingOutputFilter filter = new LogCapturingOutputFilter(prepareResult.curatedApplication, false, false,
                 () -> true);
         QuarkusConsole.addOutputFilter(filter);
@@ -138,6 +137,7 @@ private int doJavaStart(ExtensionContext context, Class<? extends QuarkusTestPro
         try {
             StartupAction startupAction = prepareResult.augmentAction.createInitialRuntimeApplication();
             Thread.currentThread().setContextClassLoader(startupAction.getClassLoader());
+            QuarkusConsole.installRedirects();
 
             QuarkusTestProfile profileInstance = prepareResult.profileInstance;
 
@@ -168,6 +168,7 @@ private int doJavaStart(ExtensionContext context, Class<? extends QuarkusTestPro
             }
             throw e;
         } finally {
+            QuarkusConsole.uninstallRedirects();
             if (originalCl != null) {
                 Thread.currentThread().setContextClassLoader(originalCl);
             }
@@ -226,8 +227,6 @@ public void afterAll(ExtensionContext context) throws Exception {
 
     @Override
     public void beforeAll(ExtensionContext context) throws Exception {
-        QuarkusConsole.installRedirects();
         currentTestClassStack.push(context.getRequiredTestClass());
-
     }
 }