oracle / graalvm-reachability-metadata

Repository which contains community-driven collection of GraalVM reachability metadata for open-source libraries.
Creative Commons Zero v1.0 Universal
367 stars 89 forks source link

MySQL fails when 'cachePrepStmts' is 'true' #549

Open philwebb opened 1 month ago

philwebb commented 1 month ago

Describe the bug This issue is described in https://stackoverflow.com/questions/79092147/springboot-3-3-4-app-hikari-mysql-and-gradlew-nativecompile.

The exception raised is:

Exception in thread "main" com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: Can not find class 'com.mysql.cj.PerConnectionLRUFactory' specified by the 'queryInfoCacheFactory' configuration property.
    at com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:584)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:571)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:98)
    at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:80)
    at com.jesusbianco.Utilities.getMySQLDataSourceConnectionPool(Utilities.java:40)
    at com.jesusbianco.Application.main(Application.java:30)
Caused by: java.sql.SQLException: Can not find class 'com.mysql.cj.PerConnectionLRUFactory' specified by the 'queryInfoCacheFactory' configuration property.
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:67)
    at com.mysql.cj.jdbc.ConnectionImpl.createPreparedStatementCaches(ConnectionImpl.java:1033)
    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:420)
    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241)
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:137)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:360)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:202)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:461)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:550)
    ... 4 more
Caused by: java.lang.ClassNotFoundException: com.mysql.cj.PerConnectionLRUFactory
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:123)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:87)
    at java.base@20.0.1/java.lang.Class.forName(DynamicHub.java:1324)
    at java.base@20.0.1/java.lang.Class.forName(DynamicHub.java:1287)
    at java.base@20.0.1/java.lang.Class.forName(DynamicHub.java:1280)
    at com.mysql.cj.jdbc.ConnectionImpl.createPreparedStatementCaches(ConnectionImpl.java:1025)

To Reproduce

Run the sample attached to the stackoverflow.com question or any MySQL example where the cachePrepStmts data source property is set to true.

Expected behavior The metadata should provide reflection hints for com.mysql.cj.PerConnectionLRUFactory.

Logs See stackoverflow.com quesstion

System Info (please complete the following information):

Additional context Add any other context about the problem here.

philwebb commented 1 month ago

In the meantime adding a src/main/resources/META-INF/native-image/com.mysql/mysql-connector-j/reflect-config.json file with the following will work around the issue:

[
  {
    "name" : "com.mysql.cj.PerConnectionLRUFactory",
    "allPublicConstructors" : true
  }
]
vjovanov commented 3 weeks ago

@philwebb thanks for reporting! Could you open a PR with these changes so we can merge them? Ideally, we would also have a test that covers the code path that is failing.

philwebb commented 3 weeks ago

@vjovanov, The issue was actually originally raised by @jbiancot. I just did some analysis. Perhaps they might be able to raise a PR.