Как исправить Старайтесь избегать инициализации класса, вызвавшего инициализацию, с помощью собственного образа GraalVM

Я пытаюсь создать собственный образ из толстого файла jar с

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

И я получаю такие сообщения об ошибках, как:

Ошибка: классы, которые должны быть инициализированы во время выполнения, были инициализированы во время построения образа: org.apache.log4j.Level класс был запрошен для инициализации во время сборки (из командной строки). org.apache.log4j.Level был инициализирован без инструментария инициализации собственного образа, и трассировку стека невозможно отследить. Старайтесь избегать инициализации класса, вызвавшего инициализацию org.apache.log4j.Level org.slf4j.log4j12.Log4jLoggerAdapter, класс был запрошен для инициализации во время сборки (из командной строки). org.slf4j.log4j12.Log4jLoggerAdapter был инициализирован без инструментария инициализации собственного образа, и трассировку стека невозможно отследить. Старайтесь избегать инициализации класса, вызвавшего инициализацию org.slf4j.log4j12.Log4jLoggerAdapter org.apache.log4j.Logger, класс был запрошен для инициализации во время сборки (из командной строки). org.apache.log4j.Logger был инициализирован без инструментария инициализации собственного образа, и трассировку стека невозможно отследить. Старайтесь избегать инициализации класса, вызвавшего инициализацию org.apache.log4j.Logger

Каковы пути и подходы к avoiding to initialize the class проблемам? Как мне разобраться с этими сообщениями?

Моя версия graavlVM - 2.0.0-java11


person Sammers    schedule 12.03.2020    source источник


Ответы (2)


Вот полный список классов, которые нужно исключить, если вы используете Slf4J и Logback:

--initialize-at-build-time=\
org.slf4j.impl.StaticLoggerBinder\
,org.slf4j.LoggerFactory\
,ch.qos.logback.classic.Logger\
,ch.qos.logback.core.spi.AppenderAttachableImpl\
,ch.qos.logback.core.status.StatusBase\
,ch.qos.logback.classic.Level\
,ch.qos.logback.core.status.InfoStatus\
,ch.qos.logback.classic.PatternLayout\
,ch.qos.logback.core.CoreConstants
person Alex Zuzin    schedule 03.03.2021
comment
Это бесполезно. Я спрашиваю о подходах к решению подобных проблем - person Sammers; 04.03.2021
comment
Это и есть подход. Вы не можете управлять инициализацией статического класса, которая используется в старых библиотеках Java (ведение журнала, JDBC и т. Д.). За более подробной информацией можно обратиться к команде GraalVM: github.com/oracle/graal/issues. - person Alex Zuzin; 05.03.2021

Эти шаги работают для меня. Я пробовал использовать slf4j и logback, log4j2, но наконец работает slf4j-simple. В основном я пытаюсь включить определенные классы, которые запускают инициализацию в --initialize-at-build-time. Вот что я делаю.

  • Добавьте параметр -H:+TraceClassInitialization в команду сборки, например:
native-image -jar my-app.jar 
-H:IncludeResources=".*.xml|.*.conf" 
-H:+ReportUnsupportedElementsAtRuntime 
-H:+TraceClassInitialization 
-H:Name=my-app
--verbose
  • Запустите его, вы увидите такую ​​ошибку:
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)
  • Вы видите одну линию, которую я обозначил. Это класс, который нужно включить.
  • Затем запустите ту же команду с дополнительным параметром --initialize-at-build-time=org.slf4j.simple.SimpleLogger
  • Запустить его. Возможно, вам придется повторить все вышеперечисленные шаги, поскольку может появиться больше ошибок. Если да, добавьте классы, разделите их запятыми.

В моем случае последняя команда выглядит так

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
person inmyth    schedule 10.09.2020
comment
Ошибка: не-логическая опция TraceClassInitialization не может использовать префикс +/-. Используйте формат TraceClassInitialization = ‹value›. Ошибка: используйте -H: + ReportExceptionStackTraces для печати трассировки стека базового исключения. - person Frank AFRIAT; 30.12.2020