在运行本机映像包装的micronaut应用程序时遇到问题。
我使用micronaut-data-hibernate-jpa
创建了一个简单的演示应用程序,并且根据文档需要添加一些db连接池。我选择了hikari并添加了这样的依赖项micronaut-jdbc-hikari
。
我使用maven作为构建工具并添加插件来构建native-imagenative-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运行应用程序时,一切正常。但是当我尝试运行打包为本机映像的应用程序时,我会遇到这样的错误
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})
您应该在native-image.properties
中使用-h:reflectionConfigurationFiles=/path/to/reflectconfig
声明反射配置
下面是这样做的文档
我在这里将Micronaut应用程序作为Graalvm本地映像进行试用。
正如标题所示,我试图使用Docker为一个基于Kotlin的Micronaut应用程序构建一个本机映像。 我已将以下依赖项添加到文件中。 一切似乎都井然有序。映像启动并似乎接受连接,但当我启动http请求时,会出现以下错误。 有没有关于如何避免上述错误的线索?
我刚刚从https://micronaut.io/launch for Java8下载了一个新项目,该项目具有以下特性: AWS lambda AWS Lambda运行时 GraalVM支持 在readme.md中,它实际上只显示了使用gradle获得本机映像的构建指令。但是用Maven怎么做呢?
我试图构建一个micronaut(V1.0.4)应用程序的本机映像。 此应用程序使用Consul作为服务发现。 我使用选项创建了应用程序: 有人知道问题出在哪里吗?
有可能在Java 16下构建本机Quarkus映像吗?没有找到任何操作说明。 不知何故,这应该是可能的,因为Oracle发布了对Java16的GraalVM支持(https://www.graalvm.org/release-notes/21_1/)
我有以下简化设置: 4)应用程序.属性 当我使用本机maven配置文件(mvn clean package-pnative)运行该文件时,我得到: 使用--report-unsupport-elements-at-runtime运行它也没有太大帮助。当我删除MyEntity类时,它在Mac+GRAALVM-CE-Java11-20.0.0上成功地编译为本机可执行文件