'H2 database compiled into a native-image is only functional as a client

After build the native image I've the following error I'm using a H2 database in file mode. Do I should understand that it's not possible to use H2 in native mode using a file DB ?

./controler-1.0-SNAPSHOT-runner -Dquarkus.datasource.url=jdbc:h2:~/Dev/controler/sic

quarkus.datasource.url=jdbc:h2:./sic quarkus.datasource.driver=org.h2.Driver

org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
        at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:473)
        at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
        at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1538)
        at org.hibernate.query.Query.getResultList(Query.java:165)
        at com.evolis.rpms.sic.controler.StatusBean.checkHostersState(StatusBean.java:100)
        at com.evolis.rpms.sic.controler.StatusBean_Subclass.checkHostersState$$superaccessor6(Unknown Source)
        at com.evolis.rpms.sic.controler.StatusBean_Subclass$$function$$12.apply(Unknown Source)
        at io.quarkus.arc.InvocationContextImpl.interceptorChainCompleted(InvocationContextImpl.java:141)
        at io.quarkus.arc.InvocationContextImpl.proceed(InvocationContextImpl.java:161)
        at io.quarkus.arc.ActivateRequestContextInterceptor.aroundInvoke(ActivateRequestContextInterceptor.java:22)
        at io.quarkus.arc.ActivateRequestContextInterceptor_Bean.intercept(Unknown Source)
        at io.quarkus.arc.InvocationContextImpl$InterceptorInvocation.invoke(InvocationContextImpl.java:254)
        at io.quarkus.arc.InvocationContextImpl.invokeNext(InvocationContextImpl.java:133)
        at io.quarkus.arc.InvocationContextImpl.proceed(InvocationContextImpl.java:157)
        at com.evolis.rpms.sic.controler.StatusBean_Subclass.checkHostersState(Unknown Source)
        at com.evolis.rpms.sic.controler.StatusBean_ClientProxy.checkHostersState(Unknown Source)
        at com.evolis.rpms.sic.controler.StatusBean_ScheduledInvoker_checkHostersState_68e943c3d502cee246226dbe51d54e7cd7502168.invoke(Unknown Source)
        at io.quarkus.scheduler.runtime.QuartzScheduler$InvokerJob.execute(QuartzScheduler.java:249)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
        ... 3 more
Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
        at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:109)
        at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:136)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:47)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)
        at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1988)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1918)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1896)
        at org.hibernate.loader.Loader.doQuery(Loader.java:936)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:339)
        at org.hibernate.loader.Loader.doList(Loader.java:2693)
        at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2540)
        at org.hibernate.loader.Loader.list(Loader.java:2502)
        at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:396)
        at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
        at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1537)
        at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1561)
        at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1529)
        ... 19 more
Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.UnsupportedOperationException: H2 database compiled into a native-image is only functional as a client: can't create an Embedded Database Session" [50000-197]
        at org.h2.message.TraceObject.logAndConvert(TraceObject.java:357)
        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:140)
        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:103)
        at org.h2.Driver.connect(Driver.java:69)
        at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:200)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:357)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:346)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:64)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
        ... 2 more
Caused by: java.lang.UnsupportedOperationException: H2 database compiled into a native-image is only functional as a client: can't create an Embedded Database Session
        at org.h2.engine.ConnectionInfo.isRemote(ConnectionInfo.java:20)
        at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:331)
        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:124)
        ... 12 more


Solution 1:[1]

Yes, at least for now, we don't support running H2 as a server in native mode. The only thing we support is connecting to a remote H2 database using the H2 JDBC client.

It didn't seem like time well spent at the time and, to be honest, I'm not sure we ever will.

If you're interested, feel free to try to get it working but it might not be easy.

Solution 2:[2]

This is now supported in quarkus.

If you want to run integration tests in native executable, you can add @QuarkusTestResource(H2DatabaseTestResource.class) on any class in your integration tests. The test suite will start and stop the embedded database as a separate process as necessary to run your tests.

Example,

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.h2.H2DatabaseTestResource;

@QuarkusTestResource(H2DatabaseTestResource.class)
public class TestResources {}

This allows you to test your application even when it is compiled into a native executable, while the database will run in the JVM as usual.

Connect to it using:

quarkus.datasource.db-kind=h2
quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:test

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Guillaume Smet
Solution 2 Sivananda Panda