hikaricp - 使用 hikari 数据源构建 micronaut 原生镜像

标签 hikaricp micronaut graalvm-native-image micronaut-data

运行打包在 native 镜像中的 micronaut 应用程序时遇到问题。

我使用 micronaut-data-hibernate-jpa 创建了简单的演示应用程序,并根据文档我需要添加一些数据库连接池。我选择了 hikari 并添加了这样的依赖 micronaut-jdbc-hikari

我使用maven作为构建工具并添加插件来构建native-image native-image-maven-plugin

native-image.properties

Args = -H:IncludeResources=logback.xml|application.yml|bootstrap.yml \
       -H:Name=demo \
       -H:Class=com.example.Application \
       -H:+TraceClassInitialization \
       --initialize-at-run-time=org.apache.commons.logging.LogAdapter$Log4jLog,org.hibernate.secure.internal.StandardJaccServiceImpl,org.postgresql.sspi.SSPIClient,org.hibernate.dialect.OracleTypesHelper \
       --initialize-at-build-time=org.postgresql.Driver,org.postgresql.util.SharedTimer,org.hibernate.engine.spi.EffectiveEntityGraph,org.hibernate.engine.spi.LoadQueryInfluencers

当我使用 jvm 运行应用程序时,一切正常。但是当我尝试运行打包为 native 镜像的相同应用程序时,我收到这样的错误

Caused by: java.lang.IllegalArgumentException: Class com.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry[] is instantiated reflectively but was never registered. Register the class by using org.graalvm.nativeimage.hosted.RuntimeReflection
    at com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.arrayHubErrorStub(SubstrateAllocationSnippets.java:280)
    at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:305)
    at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195)
    at java.lang.ThreadLocal.get(ThreadLocal.java:172)
    at com.zaxxer.hikari.util.ConcurrentBag.borrow(ConcurrentBag.java:129)
    at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:179)
    at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:161)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
    at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:38)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:104)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:134)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:250)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:258)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:246)
    at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:83)
    at org.hibernate.internal.AbstractSharedSessionContract.beginTransaction(AbstractSharedSessionContract.java:471)
    at io.micronaut.transaction.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:352)
    ... 99 common frames omitted

更新/解决方案

根据@Airy的回答,我在native-image.properties中添加了反射配置。就我而言,它看起来像这样

[
  {
    "name" : "com.zaxxer.hikari.util.ConcurrentBag",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true,
    "allDeclaredClasses" : true,
    "allPublicClasses" : true
  },
  {
    "name" : "com.zaxxer.hikari.pool.PoolEntry",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true,
    "allDeclaredClasses" : true,
    "allPublicClasses" : true
  }
]

另一个解决方案是更改 hikari 依赖项的范围来编译并将丢失的字段/类添加到提示注释中,如下所示

@TypeHint(value = {
        PostgreSQL95Dialect.class,
        SessionFactoryImpl.class,
        org.postgresql.PGProperty.class,
        UUIDGenerator.class,
        com.zaxxer.hikari.util.ConcurrentBag.class,   // In my case I have just added this line

}, accessType = {TypeHint.AccessType.ALL_PUBLIC})

整个例子你可以找到here

最佳答案

您应该在 native-image.properties 中使用 -H:ReflectionConfigurationFiles=/path/to/reflectconfig 声明反射配置

Here is the documentation for doing so

关于hikaricp - 使用 hikari 数据源构建 micronaut 原生镜像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62661284/

相关文章:

java - 实现HIkariCP时出现ResultSetImpl错误

java - HikariCP 在闲置一段时间后失去与 MySQL 的连接

java - Micronaut 与 MockitoTests

java - springboot native 图像 NoSuchMethodException : ConfigurationClassPostProcessor. <init>()

java - 配置hikari连接池

java - 在完全托管的 CloudRun 上使用 micronaut

java - Micronaut 无法实现存储库方法 : Repository. 更新(对象实体)。找不到可能的实现

Graal 编译的 JavaFX 应用程序中的 java.lang.ClassNotFoundException

java - 有没有办法在 GraalVM 原生镜像中使用 kotlin.random.Random

java - 无法注册 MBean [HikariDataSource (testdb)]