Skip to content

All Drivers except com.mysql.cj.jdbc.Driver get unregistered between integration tests groups on quarkus 3.18+ #46324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
rsassoon opened this issue Feb 17, 2025 · 8 comments · May be fixed by #47552
Labels
area/jdbc Issues related to the JDBC extensions kind/bug Something isn't working

Comments

@rsassoon
Copy link

rsassoon commented Feb 17, 2025

Describe the bug

We make use of aws advanced jdbc wrapper and when running integration tests with different test resources, i.e., grouped tests with Mysql, grouped tests with mysq and kafka, grouped tests with kafka, mysql and wiremock, only the first group passes as for the other groups the required aws driver is unregistered. Seems to be related to quarkus restarting in between groups as described in https://quarkus.io/guides/getting-started-testing#usage-of-withtestresource

> Task :integrationTest

DatabaseRepositoryIT STANDARD_OUT
    2025-02-17 22:50:02,146 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) Available JDBC drivers:
    2025-02-17 22:50:02,146 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) 1. com.mysql.cj.jdbc.Driver
    2025-02-17 22:50:02,146 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) 2. software.amazon.jdbc.Driver
    2025-02-17 22:50:02,146 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) 3. org.testcontainers.jdbc.ContainerDatabaseDriver

.....

2025-02-17 22:50:41,663 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) Available JDBC drivers:
    2025-02-17 22:50:41,663 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) 1. com.mysql.cj.jdbc.Driver
    2025-02-17 22:50:46,701 INFO  [com.spo.odd.con.fix.kaf.UpdateHandlerIT] (Test worker) Setting up Kafka producer with bootstrap servers localhost:9093

UpdateHandlerIT > should_successfully_send_messages() STANDARD_OUT
    2025-02-17 22:50:47,270 INFO  [com.spo.odd.con.fix.kaf.UpdateHandlerIT] (awaitility-thread) Received 0 messages

Available JDBC drivers:
1. com.mysql.cj.jdbc.Driver
Failed to insert start time 
java.lang.RuntimeException: Unable to get java.sql.Driver from DriverManager
        at io.agroal.pool.ConnectionFactory.newDriver(ConnectionFactory.java:130)
        at io.agroal.pool.ConnectionFactory.<init>(ConnectionFactory.java:68)
        at io.agroal.pool.ConnectionPool.<init>(ConnectionPool.java:112)
        at io.agroal.pool.DataSource.<init>(DataSource.java:37)
        at io.agroal.pool.DataSourceProvider.getDataSource(DataSourceProvider.java:21)
        at io.agroal.api.AgroalDataSource.from(AgroalDataSource.java:41)
        at io.agroal.api.AgroalDataSource.from(AgroalDataSource.java:33)
        at io.vertx.ext.jdbc.spi.impl.AgroalCPDataSourceProvider.getDataSource(AgroalCPDataSourceProvider.java:93)
        at io.vertx.ext.jdbc.impl.JDBCClientImpl.createDataSource(JDBCClientImpl.java:315)
        at io.vertx.ext.jdbc.impl.JDBCClientImpl.lambda$getDataSourceHolder$6(JDBCClientImpl.java:297)
....
 Caused by: java.sql.SQLException: No suitable driver
        at java.sql/java.sql.DriverManager.getDriver(DriverManager.java:300)
        at io.agroal.pool.ConnectionFactory.newDriver(ConnectionFactory.java:128)


ServiceHandlerIT STANDARD_OUT
    2025-02-17 22:51:05,205 INFO  [io.sma.rea.mes.kafka] (smallrye-kafka-consumer-thread-0) SRMSG18224: Executing consumer revoked re-balance listener for group 'change-notifier'

 2025-02-17 22:51:34,762 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) Available JDBC drivers:
    2025-02-17 22:51:34,762 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) 1. com.mysql.cj.jdbc.Driver
    2025-02-17 22:51:34,771 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) Available JDBC drivers:
    2025-02-17 22:51:34,772 WARN  [com.spo.odd.con.fix.rep.VertxJDBCPoolConfig] (Test worker) 1. com.mysql.cj.jdbc.Driver
    2025-02-17 22:51:34,773 ERROR [com.spo.odd.con.fix.rep.DatabaseRepository] (vert.x-eventloop-thread-2) Failed to save last poll time: java.lang.RuntimeException: Unable to get java.sql.Driver from DriverManager
        at io.agroal.pool.ConnectionFactory.newDriver(ConnectionFactory.java:130)
        at io.agroal.pool.ConnectionFactory.<init>(ConnectionFactory.java:68)
        at io.agroal.pool.ConnectionPool.<init>(ConnectionPool.java:112)
        at io.agroal.pool.DataSource.<init>(DataSource.java:37)
        at io.agroal.pool.DataSourceProvider.getDataSource(DataSourceProvider.java:21)
        at io.agroal.api.AgroalDataSource.from(AgroalDataSource.java:41)
        at io.agroal.api.AgroalDataSource.from(AgroalDataSource.java:33)
        at io.vertx.ext.jdbc.spi.impl.AgroalCPDataSourceProvider.getDataSource(AgroalCPDataSourceProvider.java:93)
        at io.vertx.ext.jdbc.impl.JDBCClientImpl.createDataSource(JDBCClientImpl.java:315)
        at io.vertx.ext.jdbc.impl.JDBCClientImpl.lambda$getDataSourceHolder$6(JDBCClientImpl.java:297)
....
 Caused by: java.sql.SQLException: No suitable driver
        at java.sql/java.sql.DriverManager.getDriver(DriverManager.java:300)
        at io.agroal.pool.ConnectionFactory.newDriver(ConnectionFactory.java:128)

We had to add a workaround to make the tests pass:

@Produces
    public JDBCPool createJdbcPool(Vertx vertx) throws SQLException {
        if (DriverManagerHelper.getRegisteredDrivers().stream()
                .noneMatch(driver -> driver.getClass().getName().equals("software.amazon.jdbc.Driver"))) {
            DriverManager.registerDriver(new software.amazon.jdbc.Driver());
        }

        return vertxJDBCPoolConfig.createJdbcPool(vertx);
    }

Worked fine in quarkus 3.17*.
I could not reproduce it with a separate project unfortunately... and can't spend much more time on this.
Consistent behaviour in different environments.

Expected behavior

Aws driver, and others, should not get unregistered between integration tests groups, or rather, should still be registered.

Actual behavior

Aws driver, and others, are unregistered, or are not registered between integration tests groups

How to Reproduce?

Not sure, tried to reproduce it with https://github.com/rsassoon/quarkus-3-18-sql-no-suitable-driver-found/tree/master
, but no success

Output of uname -a or ver

Linux TRD-L-8X1L3T3 6.8.0-53-generic #55-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 17 15:37:52 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

OpenJDK Runtime Environment Temurin-21.0.1+12 (build 21.0.1+12-LTS)

Quarkus version or git rev

3.18+

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

Gradle 8.12.1

Additional information

No response

@rsassoon rsassoon added the kind/bug Something isn't working label Feb 17, 2025
@quarkus-bot quarkus-bot bot added the area/jdbc Issues related to the JDBC extensions label Feb 17, 2025
Copy link

quarkus-bot bot commented Feb 17, 2025

/cc @barreiro (jdbc)

@geoand
Copy link
Contributor

geoand commented Feb 18, 2025

cc @yrodiere

@yrodiere yrodiere added the triage/needs-reproducer We are waiting for a reproducer. label Feb 18, 2025
@yrodiere
Copy link
Member

I could not reproduce it with a separate project unfortunately... and can't spend much more time on this.

Thanks for reporting, but please provide a reproducer if you want us to help.

If you, who are familiar with this "aws advanced jdbc wrapper", cannot reproduce this in a reasonable timeframe, you can imagine how much time it would take to me, who has never even used this thing.

@rsassoon
Copy link
Author

Yeah, I get it... will see if I find the time, but it's not only related to the aws driver, you can see that 3. org.testcontainers.jdbc.ContainerDatabaseDriver also gets unregistered between test groups...

@rsassoon
Copy link
Author

Hi @yrodiere , I managed to reproduce it in https://github.com/rsassoon/quarkus-3-18-sql-no-suitable-driver-found. Seems related to the grouping we do with tests and integration tests, if we comment out that section in build.gradle.kts, then it works as expected, otherwise the bug manifests. Locally DatabaseIT3 works fine, and DatabaseIT and DatabaseIT2 fails with the driver bug.
Please take a look, thanks!

@geoand geoand removed the triage/needs-reproducer We are waiting for a reproducer. label Feb 19, 2025
@yrodiere
Copy link
Member

Thanks for the reproducer.

If I put a few breakpoints in strategic places and run your reprocuder, I get this:

Executing DriverManager#registerDriver - com.mysql.cj.jdbc.Driver@43acf42c
Executing DriverManager#ensureDriversInitialized - INITIALIZING
Executing DriverManager#registerDriver - software.amazon.jdbc.Driver@13cb3aac
Executing DriverManager#registerDriver - org.testcontainers.jdbc.ContainerDatabaseDriver@60f41992
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverRemover#run
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#deregisterDriver - software.amazon.jdbc.Driver@13cb3aac
Executing DriverManager#deregisterDriver - org.testcontainers.jdbc.ContainerDatabaseDriver@60f41992
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING
Executing DriverManager#ensureDriversInitialized - SKIPPING

I think your problem comes from the fact that:

  1. Your AWS wrapper driver relies on the driver being initialized by java.sql.DriverManager#ensureDriversInitialized -- which, critically, will only work once, on the first call (further calls are no-ops).
  2. Quarkus has a shutdown task dedicated to removal of drivers, io.quarkus.bootstrap.classloading.DriverRemover.

Supported drivers are fine, because they get registered automatically by Quarkus (well, Agroal, I think) on startup. Others, not so much.

It used to work before, because there was code to essentially implement ensureDriversInitialized ourselves on Quarkus startup, but for completely different reasons. These reasons were no longer relevant, so I removed that code: #45540

Now, what do we do?

I tend to think that if we have a DriverRemover, we should make sure that if an app stops then starts in the same JVM/classloader, DriverManager#ensureDriversInitialized works correctly on the second start too. Maybe DriverRemover#run could reset DriverManager#driversInitialized to false? Otherwise we'll need some DriverInitializer on app start, but it will be a hassle to determine when to run it...

Or... we just revert #45540 and apply #45533 instead, and move on :/

@yrodiere
Copy link
Member

Relevant: https://quarkusio.zulipchat.com/#narrow/channel/187038-dev/topic/Resetting.20.60java.2Esql.2EDriverManager.60

Where we came to the conclusion that we probably should do this:

Or... we just revert #45540 and apply #45533 instead, and move on :/

But also that, to ensure all app runs are the same:

well, I suppose we could mitigate the issue by doing something like Thread.currentThread().setContextClassLoader(emptyClassLoader); DriverManager.drivers(); causing it to initialize with an empty list, and letting us control things by hand

@rsassoon
Copy link
Author

Thanks for looking into this @yrodiere! And for the detailed explanation!
I guess you know best how to solve this :D . If we can guarantee that whatever non default drivers are kept between initializations, that would be awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/jdbc Issues related to the JDBC extensions kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants