4

What I try to do:

  1. mvn package -Dpackaging=docker-native -Dmicronaut.runtime=lambda -Pgraalvm

  2. what I get:

Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: 
No instances of org.apache.logging.slf4j.SLF4JLogger 
are allowed in the image heap as this class should be initialized at image runtime.
  1. ok! Let me just trace the instantiation and find the issue:
[INFO] Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.apache.logging.slf4j.SLF4JLogger are allowed in the image heap as this class should be initialized at image runtime. Object has been initialized by the org.hibernate.internal.util.SerializationHelper class initializer with a trace: 
    at org.apache.logging.slf4j.SLF4JLogger.<init>(SLF4JLogger.java:41)
    at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:36)
    at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:666)
    at org.jboss.logging.Log4j2Logger.<init>(Log4j2Logger.java:36)
    at org.jboss.logging.Log4j2LoggerProvider.getLogger(Log4j2LoggerProvider.java:30)
    at org.jboss.logging.Log4j2LoggerProvider.getLogger(Log4j2LoggerProvider.java:26)
    at org.jboss.logging.Logger.getLogger(Logger.java:2465)
    at org.jboss.logging.Logger.doGetMessageLogger(Logger.java:2573)
    at org.jboss.logging.Logger.getMessageLogger(Logger.java:2530)
    at org.jboss.logging.Logger.getMessageLogger(Logger.java:2516)
    at org.hibernate.internal.CoreLogging.messageLogger(CoreLogging.java:28)
    at org.hibernate.internal.CoreLogging.messageLogger(CoreLogging.java:24)
    at org.hibernate.internal.util.SerializationHelper.<clinit>(SerializationHelper.java:47)
.  To fix the issue mark org.apache.logging.slf4j.SLF4JLogger for build-time initialization with --initialize-at-build-time=org.apache.logging.slf4j.SLF4JLogger or use the the information from the trace to find the culprit and --initialize-at-run-time=<culprit> to prevent its instantiation.

Sounds promising!

  1. Trying with --initialize-at-build-time=org.apache.logging.slf4j.SLF4JLogger:
[INFO] Error: Classes that should be initialized at run time got initialized during image building:
 org.apache.logging.log4j.util.ProviderUtil was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.ProviderUtil got initialized use --trace-class-initialization=org.apache.logging.log4j.util.ProviderUtil
org.apache.logging.log4j.util.PropertySource$Util was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.PropertySource$Util got initialized use --trace-class-initialization=org.apache.logging.log4j.util.PropertySource$Util
org.apache.logging.log4j.LogManager was unintentionally initialized at build time. To see why org.apache.logging.log4j.LogManager got initialized use --trace-class-initialization=org.apache.logging.log4j.LogManager
org.apache.logging.log4j.spi.Provider was unintentionally initialized at build time. To see why org.apache.logging.log4j.spi.Provider got initialized use --trace-class-initialization=org.apache.logging.log4j.spi.Provider
org.apache.logging.log4j.Level was unintentionally initialized at build time. To see why org.apache.logging.log4j.Level got initialized use --trace-class-initialization=org.apache.logging.log4j.Level
org.apache.logging.slf4j.SLF4JLogger$1 was unintentionally initialized at build time. To see why org.apache.logging.slf4j.SLF4JLogger$1 got initialized use --trace-class-initialization=org.apache.logging.slf4j.SLF4JLogger$1
org.apache.logging.log4j.util.Constants was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.Constants got initialized use --trace-class-initialization=org.apache.logging.log4j.util.Constants
org.apache.logging.log4j.util.LoaderUtil was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.LoaderUtil got initialized use --trace-class-initialization=org.apache.logging.log4j.util.LoaderUtil
org.apache.logging.log4j.spi.StandardLevel was unintentionally initialized at build time. To see why org.apache.logging.log4j.spi.StandardLevel got initialized use --trace-class-initialization=org.apache.logging.log4j.spi.StandardLevel
org.apache.logging.log4j.util.Strings was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.Strings got initialized use --trace-class-initialization=org.apache.logging.log4j.util.Strings
org.apache.logging.log4j.util.PropertiesUtil was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.PropertiesUtil got initialized use --trace-class-initialization=org.apache.logging.log4j.util.PropertiesUtil
org.apache.logging.log4j.status.StatusLogger was unintentionally initialized at build time. To see why org.apache.logging.log4j.status.StatusLogger got initialized use --trace-class-initialization=org.apache.logging.log4j.status.StatusLogger
org.apache.logging.log4j.spi.LoggerRegistry was unintentionally initialized at build time. To see why org.apache.logging.log4j.spi.LoggerRegistry got initialized use --trace-class-initialization=org.apache.logging.log4j.spi.LoggerRegistry


okay.... but I can try the other option!

  1. try with: --initialize-at-run-time=<culprit>. According to logs the culprit was org.hibernate.internal.util.SerializationHelper:
[INFO] Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.apache.logging.slf4j.SLF4JLogger are allowed in the image heap as this class should be initialized at image runtime. Object has been initialized by the org.hibernate.internal.log.DeprecationLogger class initializer with a trace: 
    at org.apache.logging.slf4j.SLF4JLogger.<init>(SLF4JLogger.java:41)
    at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:36)
    at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:666)
    at org.jboss.logging.Log4j2Logger.<init>(Log4j2Logger.java:36)
    at org.jboss.logging.Log4j2LoggerProvider.getLogger(Log4j2LoggerProvider.java:30)
    at org.jboss.logging.Log4j2LoggerProvider.getLogger(Log4j2LoggerProvider.java:26)
    at org.jboss.logging.Logger.getLogger(Logger.java:2465)
    at org.jboss.logging.Logger.doGetMessageLogger(Logger.java:2573)
    at org.jboss.logging.Logger.getMessageLogger(Logger.java:2530)
    at org.jboss.logging.Logger.getMessageLogger(Logger.java:2516)
    at org.hibernate.internal.log.DeprecationLogger.<clinit>(DeprecationLogger.java:29)
.  To fix the issue mark org.apache.logging.slf4j.SLF4JLogger for build-time initialization with --initialize-at-build-time=org.apache.logging.slf4j.SLF4JLogger or use the the information from the trace to find the culprit and --initialize-at-run-time=<culprit> to prevent its instantiation.

Looks like there wasn't only one culprit? okay this time for sure it will work!

  1. including second cuplrit:
[INFO] Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: 
No instances of org.apache.logging.slf4j.SLF4JLogger are allowed in the image heap as this class should be initialized at image runtime. 
Object has been initialized by the org.hibernate.internal.SessionFactoryRegistry class initializer with a trace: 

There is no end to this!

  1. Going for the whole package: --initialize-at-run-time=org.hibernate:
[INFO] Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.apache.logging.slf4j.SLF4JLogger are allowed in the image heap as this class should be initialized at image runtime. Object has been initialized by the org.hibernate.internal.util.SerializationHelper class initializer with a trace:
  1. Let's try to go back to --initialize-at-build-time=org.apache.logging.slf4j.SLF4JLogger but instead specify the whole package: --initialize-at-build-time=org.apache.logging
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  02:08 min
[INFO] Finished at: 2022-10-14T16:33:04+03:00
[INFO] ------------------------------------------------------------------------

It's built! Now let's see if it runs!

...
Caused by: com.amazonaws.serverless.exceptions.ContainerInitializationException: Error starting Micronaut container: Bean definition [io.micronaut.configuration.hibernate.jpa.conf.SessionFactoryPerDataSourceFactory] could not be loaded: Error instantiating bean of type  [io.micronaut.configuration.hibernate.jpa.conf.SessionFactoryPerDataSourceFactory]
...
Caused by: java.lang.NoSuchMethodException: org.apache.logging.log4j.message.ParameterizedMessageFactory.<init>()
...

At this point I'm out of options.

  • GRAALVM_VERSION: 22.2.0
  • GRAALVM_JVM_VERSION: java17
  • GRAALVM_ARCH: amd64
  • CLASS_NAME: io.micronaut.function.aws.runtime.MicronautLambdaRuntime
  • pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>moe.sigeemu</groupId>
  <artifactId>si-gameless</artifactId>
  <version>0.1</version>
  <packaging>${packaging}</packaging>

  <parent>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-parent</artifactId>
    <version>3.7.1</version>
  </parent>

  <properties>
    <packaging>jar</packaging>
    <jdk.version>17</jdk.version>
    <release.version>17</release.version>
    <micronaut.version>3.7.1</micronaut.version>
    <exec.mainClass>io.micronaut.function.aws.runtime.MicronautLambdaRuntime</exec.mainClass>
    <micronaut.test.resources.enabled>true</micronaut.test.resources.enabled>
    <micronaut.runtime>lambda</micronaut.runtime>
    <micronaut.data.version>3.8.0</micronaut.data.version>
    <vavr.version>0.10.3</vavr.version>
  </properties>

  <repositories>
    <repository>
      <id>central</id>
      <url>https://repo.maven.apache.org/maven2</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-inject</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-validation</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.aws</groupId>
      <artifactId>micronaut-function-aws-api-proxy</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.aws</groupId>
      <artifactId>micronaut-function-aws-api-proxy-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.aws</groupId>
      <artifactId>micronaut-function-aws-custom-runtime</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-http-client</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-jackson-databind</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-xml</artifactId>
      <version>2.11.1</version>
    </dependency>
    <dependency>
      <groupId>io.vavr</groupId>
      <artifactId>vavr</artifactId>
      <version>${vavr.version}</version>
    </dependency>
    <dependency>
      <groupId>io.micronaut.aws</groupId>
      <artifactId>micronaut-aws-sdk-v2</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>s3</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.data</groupId>
      <artifactId>micronaut-data-hibernate-jpa</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.flyway</groupId>
      <artifactId>micronaut-flyway</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.graphql</groupId>
      <artifactId>micronaut-graphql</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.sql</groupId>
      <artifactId>micronaut-jdbc-hikari</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.annotation</groupId>
      <artifactId>jakarta.annotation-api</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.flywaydb</groupId>
      <artifactId>flyway-mysql</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.test</groupId>
      <artifactId>micronaut-test-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <scope>test</scope>
    </dependency>


    <dependency>
      <groupId>com.graphql-java-generator</groupId>
      <artifactId>graphql-java-runtime</artifactId>
      <version>1.18</version>
      <exclusions>
        <exclusion>
          <groupId>com.graphql-java</groupId>
          <artifactId>graphql-java-spring-boot-starter-webmvc</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.graphql-java-generator</groupId>
          <artifactId>graphql-java-spring-mvc</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>io.micronaut.build</groupId>
        <artifactId>micronaut-maven-plugin</artifactId>
        <configuration>
          <nativeImageBuildArgs combine.children="append">
            <nativeImageBuildArg>--trace-object-instantiation=org.apache.logging.slf4j.SLF4JLogger</nativeImageBuildArg>
<!--            <nativeImageBuildArg>&#45;&#45;initialize-at-run-time=org.hibernate.internal.log.DeprecationLogger</nativeImageBuildArg>-->
            <nativeImageBuildArg>--initialize-at-build-time=org.apache.logging</nativeImageBuildArg>
          </nativeImageBuildArgs>
        </configuration>
      </plugin>
      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <!-- Uncomment to enable incremental compilation -->
          <!-- <useIncrementalCompilation>false</useIncrementalCompilation> -->

          <annotationProcessorPaths combine.self="override">
            <path>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <version>${lombok.version}</version>
            </path>
            <path>
              <groupId>io.micronaut</groupId>
              <artifactId>micronaut-inject-java</artifactId>
              <version>${micronaut.version}</version>
            </path>
            <path>
              <groupId>io.micronaut.data</groupId>
              <artifactId>micronaut-data-processor</artifactId>
              <version>${micronaut.data.version}</version>
            </path>
            <path>
              <groupId>io.micronaut</groupId>
              <artifactId>micronaut-graal</artifactId>
              <version>${micronaut.version}</version>
            </path>
            <path>
              <groupId>io.micronaut</groupId>
              <artifactId>micronaut-http-validation</artifactId>
              <version>${micronaut.version}</version>
            </path>
            <path>
              <groupId>io.micronaut</groupId>
              <artifactId>micronaut-validation</artifactId>
              <version>${micronaut.version}</version>
            </path>
          </annotationProcessorPaths>
          <compilerArgs>
            <arg>-Amicronaut.processing.group=moe.sigeemu</arg>
            <arg>-Amicronaut.processing.module=si-gameless</arg>
          </compilerArgs>
        </configuration>
      </plugin>
      <plugin>
        <groupId>com.graphql-java-generator</groupId>
        <artifactId>graphql-maven-plugin</artifactId>
        <version>1.18</version>
        <executions>
          <execution>
            <goals>
              <goal>generateClientCode</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <packageName>moe.sigeemu.domain.model.graphql.generated</packageName>
          <copyRuntimeSources>false</copyRuntimeSources>
          <generateDeprecatedRequestResponse>false</generateDeprecatedRequestResponse>
          <separateUtilityClasses>true</separateUtilityClasses>

          <customScalars>
            <customScalar>
              <graphQLTypeName>CountryCode</graphQLTypeName>
              <javaType>com.nimbusds.openid.connect.sdk.assurance.claims.ISO3166_1Alpha2CountryCode</javaType>
              <graphQLScalarTypeStaticField>moe.sigeemu.domain.model.scalars.GraphQLScalarTypeCountryCode.CountryCode</graphQLScalarTypeStaticField>
            </customScalar>
            <customScalar>
              <graphQLTypeName>FuzzyDateInt</graphQLTypeName>
              <javaType>java.time.LocalDate</javaType>
              <graphQLScalarTypeStaticField>moe.sigeemu.domain.model.scalars.GraphQLScalarTypeFuzzyDateInt.FuzzyDateInt</graphQLScalarTypeStaticField>
            </customScalar>
            <customScalar>
              <graphQLTypeName>Json</graphQLTypeName>
              <javaType>com.fasterxml.jackson.databind.JsonNode</javaType>
              <graphQLScalarTypeStaticField>moe.sigeemu.domain.model.scalars.GraphQLScalarTypeJson.Json</graphQLScalarTypeStaticField>
            </customScalar>
          </customScalars>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

A cry for help to anyone who was able to read through this post and knows a little bit more about Micronaut and GraalVM: what am doing wrong? I'm desperate and want to go back to Spring since there is little to no info on the internet about native images T_T

Spica
  • 63
  • 6
  • I'm facing that exact same issue with a Spring Boot 3 codebase FYI, I believe it's still WIP on Log4j2's side, see https://issues.apache.org/jira/browse/LOG4J2-2649. – sp00m Oct 24 '22 at 14:45
  • @sp00m it seems like the same problem occurs with Logback too, not only Log4j – Spica Oct 25 '22 at 17:53

1 Answers1

1

I had a similar issue:

First I had this error:

UnresolvedElementException: Discovered unresolved method during parsing: io.netty.util.internal.logging.Log4J2Logger

Then after adding the following dependency: implementation("org.jboss.logmanager:log4j2-jboss-logmanager") as documented here on Quarkus website I had this one:

Discovered unresolved type during parsing: org.apache.log4j.Logger

I finally added these two dependencies and I was passed that Logging related errors and on to other but its ok, its progress!!!

implementation("org.jboss.logging:commons-logging-jboss-logging")
implementation("org.jboss.logmanager:log4j-jboss-logmanager")
implementation("org.jboss.slf4j:slf4j-jboss-logmanager")
Hamady C.
  • 1,205
  • 11
  • 13