15

I try configure apache kafka in spring boot application. I read this documentation and follow the steps:

1) I add this lines to aplication.yaml:

spring:
  kafka:
    bootstrap-servers: kafka_host:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringDeserializer
      value-serializer: org.apache.kafka.common.serialization.ByteArraySerializer

2) I create new Topic:

    @Bean
    public NewTopic responseTopic() {
        return new NewTopic("new-topic", 5, (short) 1);
    }

And now I want use KafkaTemplate:

private final KafkaTemplate<String, byte[]> kafkaTemplate;

public KafkaEventBus(KafkaTemplate<String, byte[]> kafkaTemplate) {
    this.kafkaTemplate = kafkaTemplate;
}

But Intellij IDE highlights:

enter image description here

To fix this I need create bean:

@Bean
public KafkaTemplate<String, byte[]> myMessageKafkaTemplate() {
    return new KafkaTemplate<>(greetingProducerFactory());
}

And pass to constructor propirties greetingProducerFactory():

@Bean
public ProducerFactory<String, byte[]> greetingProducerFactory() {
    Map<String, Object> configProps = new HashMap<>();
    configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka_hist4:9092");
    configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class);
    return new DefaultKafkaProducerFactory<>(configProps);
}

But then what's the point of setting in application.yaml if I need create ProducerFactory manual?

ip696
  • 6,574
  • 12
  • 65
  • 128

3 Answers3

7

I think you can safely ignore IDEA's warning; I have no problems wiring in Boot's template with different generic types...

@SpringBootApplication
public class So55280173Application {

    public static void main(String[] args) {
        SpringApplication.run(So55280173Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(KafkaTemplate<String, String> template, Foo foo) {
        return args -> {
            template.send("so55280173", "foo");
            if (foo.template == template) {
                System.out.println("they are the same");
            }
        };
    }

    @Bean
    public NewTopic topic() {
        return new NewTopic("so55280173", 1, (short) 1);
    }

}

@Component
class Foo {

    final KafkaTemplate<String, String> template;

    @Autowired
    Foo(KafkaTemplate<String, String> template) {
        this.template = template;
    }

}

and

they are the same
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • I get error: `Failed to construct kafka producer` when try send message – ip696 Mar 21 '19 at 13:21
  • That has nothing to with wiring; I suggest you ask a new question with more information, stack trace etc. – Gary Russell Mar 21 '19 at 13:24
  • I confused the serializer and deserializer classes for the key so there was an error `Failed to construct kafka producer`. Now It work, but IDEA still show warning(Because of this, I did not understand much and thought that it was necessary to create manually) – ip696 Mar 21 '19 at 14:27
  • Sounds like IDEA is more strict than spring :( – Gary Russell Mar 21 '19 at 15:23
5

By default KafkaTemplate<Object, Object> is created by Spring Boot in KafkaAutoConfiguration class. Since Spring considers generic type information during dependency injection the default bean can't be autowired into KafkaTemplate<String, byte[]>.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
2

I had the same issue initially, but when I executed it gave no errors and worked fine.

Ignore Intellij IDEA's warning, it may be a IDEA's bug figuring out autowired components.

Jai Gohil
  • 61
  • 6