Skip to content
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

GraalVM native error on micronaut-vertx-pg-client #838

Open
pjgg opened this issue Mar 28, 2023 · 0 comments
Open

GraalVM native error on micronaut-vertx-pg-client #838

pjgg opened this issue Mar 28, 2023 · 0 comments

Comments

@pjgg
Copy link

pjgg commented Mar 28, 2023

Expected Behavior

I would expect that dependency micronaut-vertx-pg-client add all the required GraalVM configuration in order to be able to compile/run my "micronaut-vertx-pg-client" application in native mode.

Actual Behaviour

Given a simple app with the following dependencies:

dependencies {
    implementation('com.ongres.scram:client:2.1')
    implementation("io.micronaut.sql:micronaut-vertx-pg-client")
    implementation("io.micronaut.rxjava2:micronaut-rxjava2")
    implementation("io.micronaut:micronaut-runtime")
    runtimeOnly("ch.qos.logback:logback-classic")
    implementation("io.micronaut:micronaut-inject")
    implementation ('io.micronaut:micronaut-management')
}

App:

package com.example;

import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.reactivex.Single;

import io.vertx.reactivex.pgclient.PgPool;
import io.vertx.reactivex.sqlclient.Row;
import io.vertx.reactivex.sqlclient.RowIterator;
import jakarta.inject.Inject;

@Controller("/postgres")
public class HelloWorldController {

    @Inject
    PgPool pgClient;

    @Get("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String index() {
        return "Hello World";
    }

    @Get
    @Produces(MediaType.TEXT_PLAIN)
    public Single<String> getPostgresVersion() {
        return  pgClient.query("SELECT version()")
                .rxExecute()
                .map(rows -> {
                    RowIterator<Row> rowIt = rows.iterator();
                    if (rowIt.hasNext()) {
                        return rowIt.next().getString("version");
                    }

                    return "";
                });
    }
}

application.yml

micronaut:
  application:
    name: micronaut-demo
  server:
    port: 8080
vertx:
  pg:
    client:
      port: 5432
      host: localhost
      database: mydb
      user: user
      password: topsecret
      maxSize: 5

When I compile my app with GraalVM ./gradlew clean nativeCompile

native-image.properties

Args = --initialize-at-run-time=io.vertx.pgclient.impl.codec.DataTypeCodec \
       --trace-class-initialization=io.vertx.core.logging.LoggerFactory \
       --allow-incomplete-classpath \
       --enable-all-security-services \
       -H:IncludeResources=logback.xml|application.yml \
       -H:Name=rxjava-app \
       -H:Class=com.example.Application \
       -H:ReflectionConfigurationResources=${.}/reflection.json \
       -H:+ReportUnsupportedElementsAtRuntime

reflection.json

[
  {
    "name": "io.vertx.pgclient.impl.codec.DataTypeCodec",
    "allDeclaredConstructors": true,
    "allDeclaredMethods": true
  }
]

and then make a query to localhost:8080/postgres I am getting the following error:

.18:33:38.396 [vert.x-eventloop-thread-13] ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: Could not initialize class io.vertx.pgclient.impl.codec.DataTypeCodec
java.lang.NoClassDefFoundError: Could not initialize class io.vertx.pgclient.impl.codec.DataTypeCodec

If I swap the graalVM config property initialize-at-run-time to initialize-at-build-time then I am getting the following compile error:

Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of io.vertx.core.logging.SLF4JLogDelegate are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=io.vertx.core.logging.SLF4JLogDelegate.

Because looks like pgClient internally is using a Log library that needs to be initialized at runtime but it also seems that DataTypeCodec needs to be initialized at build time, so looks like a chicken-egg problem

Steps To Reproduce

Just create a hello world app like this one:

package com.example;

import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.reactivex.Single;

import io.vertx.reactivex.pgclient.PgPool;
import io.vertx.reactivex.sqlclient.Row;
import io.vertx.reactivex.sqlclient.RowIterator;
import jakarta.inject.Inject;

@Controller("/postgres")
public class HelloWorldController {

    @Inject
    PgPool pgClient;

    @Get("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String index() {
        return "Hello World";
    }

    @Get
    @Produces(MediaType.TEXT_PLAIN)
    public Single<String> getPostgresVersion() {
        return  pgClient.query("SELECT version()")
                .rxExecute()
                .map(rows -> {
                    RowIterator<Row> rowIt = rows.iterator();
                    if (rowIt.hasNext()) {
                        return rowIt.next().getString("version");
                    }

                    return "";
                });
    }
}

and try to compile with GraalVM and make a Query to /postgres

Environment Information

openjdk 17.0.5 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08)
Fedora 37

Example Application

No response

Version

3.8.7

@pjgg pjgg changed the title GlaaVM native error on micronaut-vertx-pg-client GraalVM native error on micronaut-vertx-pg-client Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant