Search code examples
javaspring-bootspring-kafkaapache-kafka-streamsgraalvm

Spring-boot kafka app to GraalVM native image - org.apache.kafka.streams.processor.internals.DefaultKafkaClientSupplier could not be found


I have Java Spring-boot application using spring-kafka and kafka-streams. I'm trying to build GraalVM native image with

 mvn -Pnative spring-boot:build-image

The build is successful but when I try to run the image in docker I get exception:

Caused by: org.apache.kafka.common.config.ConfigException: Invalid value org.apache.kafka.streams.processor.internals.DefaultKafkaClientSupplier for configuration default.client.supplier: Class org.apache.kafka.streams.processor.internals.DefaultKafkaClientSupplier could not be found.
        at org.apache.kafka.common.config.ConfigDef.parseType(ConfigDef.java:747)
        at org.apache.kafka.common.config.ConfigDef$ConfigKey.<init>(ConfigDef.java:1175)
        at org.apache.kafka.common.config.ConfigDef.define(ConfigDef.java:155)
        at org.apache.kafka.common.config.ConfigDef.define(ConfigDef.java:175)
        at org.apache.kafka.common.config.ConfigDef.define(ConfigDef.java:214)
        at org.apache.kafka.common.config.ConfigDef.define(ConfigDef.java:376)
        at org.apache.kafka.common.config.ConfigDef.define(ConfigDef.java:389)
        at org.apache.kafka.streams.StreamsConfig.<clinit>(StreamsConfig.java:1008)
        ... 16 common frames omitted

Kafka config:

spring:
  kafka:
    producer:
      value-serializer: "org.springframework.kafka.support.serializer.JsonSerializer"
      properties:
        spring:
          json:
            type:
              mapping: "ErrorReportDomain:com.kt.kafka.messagingprocessor.domain.ErrorReportDomain"
    client-id: messaging-processor
    bootstrap-servers:
      - "XXX"
    security:
      protocol: SASL_PLAINTEXT
    properties:
      sasl:
        mechanism: SCRAM-SHA-512
        jaas:
          config: org.apache.kafka.common.security.scram.ScramLoginModule required username="XXX" password="XXX";
    streams:
      application.id: messaging-processor
      properties:
        spring:
          json:
            trusted:
              packages: '*'
        default:
          key:
            serde: org.apache.kafka.common.serialization.Serdes$StringSerde
          value:
            serde: org.springframework.kafka.support.serializer.JsonSerde

Any suggestion please?


Solution

  • We recently added Kafka Streams hints into GraalVM Reachability Metadata: https://github.com/oracle/graalvm-reachability-metadata/pull/422.

    But apparently that has not been released yet.

    So, to make it working in your app, you need to provide those hints manually.

    It looks like you don't use Spring Cloud Stream, so I suggest to copy/paste this class into your project: https://github.com/spring-cloud/spring-cloud-stream/blob/main/binders/kafka-binder/spring-cloud-stream-binder-kafka-streams/src/main/java/org/springframework/cloud/stream/binder/kafka/streams/aot/KafkaStreamsBinderRuntimeHints.java

    Probably with some modification removing Spring Cloud Stream specific entries.

    See more docs about manual hints registration: https://docs.spring.io/spring-framework/reference/core/aot.html#aot.hints