dimanche 23 juillet 2023

How to register method for runtime reflection with GraalVM?

I am trying to get an existing Java application running with GraalVM. Now I have encountered an issue i don't know how to solve. I was able to successfully create a native image. However I had to create a reflection configuration like this to overcome the "Warning: Reflection method java.lang.Class.getMethod invoked" message during the compile phase:

[
  {
    "name": "java.lang.Class",
    "queryAllDeclaredConstructors": true,
    "queryAllPublicConstructors": true,
    "queryAllDeclaredMethods": true,
    "queryAllPublicMethods": true,
    "allDeclaredClasses": true,
    "allPublicClasses": true
  },
  {
    "name": "org.apache.logging.log4j.message.DefaultFlowMessageFactory",
    "queryAllDeclaredConstructors": true,
    "queryAllPublicConstructors": true,
    "queryAllDeclaredMethods": true,
    "queryAllPublicMethods": true,
    "allDeclaredClasses": true,
    "allPublicClasses": true
  }
]

I've added the second entry, because my native image was throwing a method-not-found error for org.apache.logging.log4j.message.DefaultFlowMessageFactory.<init>

When I run my native image now, I get the following error:

Exception in thread "main" org.graalvm.nativeimage.MissingReflectionRegistrationError: The program tried to reflectively invoke method public org.apache.logging.log4j.message.DefaultFlowMessageFactory() without it being registered for runtime reflection. Add it to the reflection metadata to solve this problem. See https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection for help.
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils.forQueriedOnlyExecutable(MissingReflectionRegistrationUtils.java:97)
    at java.base@17.0.8/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:74)
    at java.base@17.0.8/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:496)
    at java.base@17.0.8/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
    at java.base@17.0.8/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:347)
    at java.base@17.0.8/java.lang.Class.newInstance(DynamicHub.java:645)
    at org.apache.logging.log4j.spi.AbstractLogger.createDefaultFlowMessageFactory(AbstractLogger.java:240)
    at org.apache.logging.log4j.spi.AbstractLogger.<init>(AbstractLogger.java:141)
    at org.apache.logging.log4j.status.StatusLogger.<init>(StatusLogger.java:141)
    at org.apache.logging.log4j.status.StatusLogger.<clinit>(StatusLogger.java:91)
    at org.apache.logging.slf4j.Log4jMarkerFactory.<clinit>(Log4jMarkerFactory.java:36)
    at org.apache.logging.slf4j.SLF4JServiceProvider.initialize(SLF4JServiceProvider.java:53)
    at org.slf4j.LoggerFactory.bind(LoggerFactory.java:183)
    at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:170)
    at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:455)
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:441)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:390)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:416)
    at app.Main.<clinit>(Main.java:12)

The error message implies that I might be able to solve this problem my registering this method for runtime reflection.

OK, But how? I couldn't find anything helpful in the documentation.

Any ideas? Are there any examples I might have missed?





Aucun commentaire:

Enregistrer un commentaire