Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix "Try avoiding to initialize the class that caused initialization" with GraalVM native-image

I'm trying to create a native-image from a fat jar file with

$ native-image -H:+TraceClassInitialization --initialize-at-run-time=org.slf4j,org.apache.log4j \
               -jar ./my-jar-with-dependencies.jar

And I'm getting those error messages like:

Error: Classes that should be initialized at run time got initialized during image building: org.apache.log4j.Level the class was requested to be initialized at build time (from the command line). org.apache.log4j.Level has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked. Try avoiding to initialize the class that caused initialization of org.apache.log4j.Level org.slf4j.log4j12.Log4jLoggerAdapter the class was requested to be initialized at build time (from the command line). org.slf4j.log4j12.Log4jLoggerAdapter has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked. Try avoiding to initialize the class that caused initialization of org.slf4j.log4j12.Log4jLoggerAdapter org.apache.log4j.Logger the class was requested to be initialized at build time (from the command line). org.apache.log4j.Logger has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked. Try avoiding to initialize the class that caused initialization of org.apache.log4j.Logger

What are the ways and approaches to avoiding to initialize the class issues? How can I deal with those messages?

My graavlVM version is 2.0.0-java11

like image 563
Sammers Avatar asked Mar 12 '20 12:03

Sammers


1 Answers

These steps work for me. I've tried using slf4j and logback, log4j2 but the one that finally works is slf4j-simple. Basically I try to include specific classes that trigger the initialization in --initialize-at-build-time. Here's what I do.

  • Add parameter -H:+TraceClassInitialization on the build command, like this:
native-image -jar my-app.jar 
-H:IncludeResources=".*.xml|.*.conf" 
-H:+ReportUnsupportedElementsAtRuntime 
-H:+TraceClassInitialization 
-H:Name=my-app
--verbose
  • Run it, you will see some error like this:
Error: Classes that should be initialized at run time got initialized during image building:
 org.slf4j.simple.SimpleLogger was unintentionally initialized at build time. io.netty.channel.AbstractChannel caused initialization of this class with the following trace:
        at org.slf4j.simple.SimpleLogger.<clinit>(SimpleLogger.java) // THIS IS THE OFFENDING CLASS
        at org.slf4j.simple.SimpleLoggerFactory.<init>(SimpleLoggerFactory.java:45)
        at org.slf4j.simple.SimpleServiceProvider.initialize(SimpleServiceProvider.java:43)
  • You see the one line I marked. That is the class to be included.
  • Next run the same command with extra parameter --initialize-at-build-time=org.slf4j.simple.SimpleLogger
  • Run it. You may need to repeat all the above steps as there could be more errors showing up. If so add the classes, separate them with commas.

In my case the final command looks like this

native-image -jar my-app.jar 
-H:IncludeResources=".*.xml|.*.conf" 
-H:+ReportUnsupportedElementsAtRuntime 
-H:+TraceClassInitialization 
--initialize-at-build-time=org.slf4j.simple.SimpleLogger,org.slf4j.LoggerFactory
-H:Name=my-app
--verbose
like image 113
inmyth Avatar answered Sep 28 '22 04:09

inmyth