Repository: quarkusio/quarkus
Issue: No suitable driver found for Postgresql with TestContainers since Quarkus 1.8

**Describe the bug**

I have a TestContainers test that pings a Postgres DB. This test does not actually use Quarkus but I realized that it was working in 1.7.3 and failing in 1.8.

It is not a stopper for me (as I said, I realized I should have taken the `@QuarkusTest` annotation) but it sounds that something has been introduced that it makes this test fail (this test has been working since Quarkus 1.6 at least).

**Expected behavior**

The test should pass as in 1.7.3

**Actual behavior**

The test fail with:

```
java.sql.SQLException: No suitable driver found for jdbc:postgresql://localhost:32831/vintageStoreDB?loggerLevel=OFF
        at org.acme.PingPostgreSQLTest.shouldPingPostgreSQL(PingPostgreSQLTest.java:32)
```

**To Reproduce**

Generate a brand new Quarkus 1.7.3-Final  app with the Postgres extension. Then, add the TestContainers dependency:

```
  <properties>
   ...
    <testcontainers.version>1.14.3</testcontainers.version>
  </properties>

    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>postgresql</artifactId>
      <version>${testcontainers.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>${testcontainers.version}</version>
      <scope>test</scope>
    </dependency>
```

Now create a new Test

```
@QuarkusTest
@Testcontainers
public class PingPostgreSQLTest {

  @Container
  public static PostgreSQLContainer pg = new PostgreSQLContainer<>("postgres:12.4")
    .withDatabaseName("vintageStoreDB")
    .withUsername("vintage")
    .withPassword("vintage")
    .withExposedPorts(5432);

  @Test
  public void shouldPingPostgreSQL() throws Exception {
    pg.start();

    try (Connection con = DriverManager.getConnection(pg.getJdbcUrl(), pg.getUsername(), pg.getPassword());
         Statement st = con.createStatement();
         ResultSet rs = st.executeQuery("SELECT VERSION()")) {

      if (rs.next()) {
        assertTrue(rs.getString(1).contains("PostgreSQL 12"));
      } else {
        throw new Exception();
      }
    }

    pg.stop();
  }
}
```

This test just uses TestContainers to ping a Postgres db. It doesn't use any Quarkus. In fact, if you leave the `@QuarkusTest` annotation it also works. Then, move to Quarkus 1.8.0, it fails.


**Configuration**

The test with 1.7.3 works even without any `application.properties` file declaring a Postgres driver or JDBC URL. 
Because it is now failing with 1.8 I tried to add `quarkus.datasource.db-kind=postgresql` and so on.

**Environment (please complete the following information):**
 - Output of `uname -a` or `ver`: Darwin iMac-Pro-de-Antonio.local 19.6.0 Darwin Kernel Version 19.6.0: Thu Jun 18 20:49:00 PDT 2020; root:xnu-6153.141.1~1/RELEASE_X86_64 x86_64
 - Output of `java -version`: java version "11.0.6" 2020-01-14 LTS
 - GraalVM version (if different from Java): 
 - Quarkus version or git rev: 1.8.0-Final
 - Build tool (ie. output of `mvnw --version` or `gradlew --version`): 3.6.3_1

**Additional context**
(Add any other context about the problem here.)


Changed files:
independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DriverRemover.java
independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java

diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DriverRemover.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DriverRemover.java
index 283ea4c8af9..99176b1dff7 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DriverRemover.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DriverRemover.java
@@ -10,13 +10,21 @@ public class DriverRemover implements Runnable {
 
     private static final Logger log = Logger.getLogger(DriverRemover.class);
 
+    final ClassLoader goingAwayCl;
+
+    public DriverRemover(ClassLoader goingAwayCl) {
+        this.goingAwayCl = goingAwayCl;
+    }
+
     @Override
     public void run() {
         Enumeration<Driver> drivers = DriverManager.getDrivers();
         while (drivers.hasMoreElements()) {
             Driver driver = drivers.nextElement();
             try {
-                DriverManager.deregisterDriver(driver);
+                if (driver.getClass().getClassLoader() == goingAwayCl) {
+                    DriverManager.deregisterDriver(driver);
+                }
             } catch (SQLException t) {
                 log.error("Failed to deregister driver", t);
             }
diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java
index 61dae72b5b6..c7ffad2f2e9 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java
@@ -8,6 +8,7 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.ProtectionDomain;
+import java.sql.Driver;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -84,6 +85,7 @@ public class QuarkusClassLoader extends ClassLoader implements Closeable {
     }
 
     private boolean closed;
+    private volatile boolean driverLoaded;
 
     private QuarkusClassLoader(Builder builder) {
         //we need the parent to be null
@@ -397,8 +399,12 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
                     if (classPathElementResource != null) { //can happen if the class loader was closed
                         byte[] data = classPathElementResource.getData();
                         definePackage(name, classPathElement);
-                        return defineClass(name, data, 0, data.length,
+                        Class<?> cl = defineClass(name, data, 0, data.length,
                                 protectionDomains.computeIfAbsent(classPathElement, (ce) -> ce.getProtectionDomain(this)));
+                        if (Driver.class.isAssignableFrom(cl)) {
+                            driverLoaded = true;
+                        }
+                        return cl;
                     }
                 }
 
@@ -481,14 +487,17 @@ public void close() {
             }
             closed = true;
         }
-        //DriverManager only lets you remove drivers with the same CL as the caller
-        //so we need do define the cleaner in this class loader
-        try (InputStream is = getClass().getResourceAsStream("DriverRemover.class")) {
-            byte[] data = JarClassPathElement.readStreamContents(is);
-            Runnable r = (Runnable) defineClass(DriverRemover.class.getName(), data, 0, data.length).newInstance();
-            r.run();
-        } catch (Exception e) {
-            log.debug("Failed to clean up DB drivers");
+        if (driverLoaded) {
+            //DriverManager only lets you remove drivers with the same CL as the caller
+            //so we need do define the cleaner in this class loader
+            try (InputStream is = getClass().getResourceAsStream("DriverRemover.class")) {
+                byte[] data = JarClassPathElement.readStreamContents(is);
+                Runnable r = (Runnable) defineClass(DriverRemover.class.getName(), data, 0, data.length)
+                        .getConstructor(ClassLoader.class).newInstance(this);
+                r.run();
+            } catch (Exception e) {
+                log.debug("Failed to clean up DB drivers");
+            }
         }
         for (ClassPathElement element : elements) {
             //note that this is a 'soft' close