Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 [email protected]/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:74)
    at [email protected]/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:496)
    at [email protected]/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
    at [email protected]/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:347)
    at [email protected]/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?

like image 615
skylar Avatar asked Feb 04 '26 04:02

skylar


1 Answers

I faced a similar issue today (spring-boot-3.1.2) and I could fix it by doing the following:

  1. mvn -Pnative native:compile
  2. java -Dspring.aot.enabled=true -agentlib:native-image-agent=config-output-dir=./config -jar target/<your-app.jar> (this will create a config folder in the root dir of your app)
  3. try testing your application with all the possible paths covered so that reflection-config.json has all the information regarding the reflection calls at run time, once done use Ctrl+C to stop the app
  4. create a folder META-INF/native-image in src/main/resources
  5. copy all the contents here(META-INF/native-image) from config folder created in step 2 enter image description here
  6. again run mvn -Pnative native:compile OR mvn -Pnative spring-boot:build-image (if you need docker image)
  7. finally run target/your-app-name (or docker run...)

I hope this helps, however, I am a newbie as far as graalVM and spring boot native apps/images are concerned, trying to learn.

like image 127
sanjeev k Avatar answered Feb 05 '26 21:02

sanjeev k



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!