'Can't find KafkaTemplate bean, even though I've defined one
My environment context looks like this:
- Spring Boot v2.5.12
- Maven Multi Module project (this is a module, it imports its Spring Boot dependencies from the parent pom)
- JDK 11
And the error that I am receiving looks like this:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of constructor in com.example.group.service.SomeServiceImpl required a bean of type 'org.springframework.kafka.core.KafkaTemplate' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.kafka.core.KafkaTemplate' in your configuration.
The relevant files:
<!-- ${base.dir}/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>
<parent>
<groupId>com.example</groupId>
<artifactId>master-config</artifactId>
<version>1.1.2</version>
</parent>
<groupId>com.example.group</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>app1</module>
<module>app2</module>
</modules>
<properties>
<java.version>11</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<spring.boot.version>2.5.12</spring.boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Omitted -->
</dependencies>
</dependencyManagement>
</project>
<!-- ${base.dir}/app2/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>
<parent>
<groupId>com.example.group</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>app2</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
// ${base.dir}/app2/src/main/java/com/example/group/SomeApplication.java
package com.example.group;
/* Imports omitted */
@SpringBootApplication
public class SomeApplication {
public static void main(String[] args) {
SpringApplication.run(SomeApplication.class, args);
}
}
// ${base.dir}/app2/src/main/java/com/example/group/configuration/AppConfig.java
package com.example.group.configuration;
/* Imports omitted */
@Configuration
public class AppConfig {
@Bean
public KafkaTemplate<Bytes, Object> kafkaTemplate(ProducerFactory<Bytes, Object> kafkaProducerFactory) {
return new KafkaTemplate<>(kafkaProducerFactory);
}
@Bean
public ProducerFactory<Bytes, Object> kafkaProducerFactory() {
Map<String, Object> producerProperties = /* Config omitted */;
return new DefaultKafkaProducerFactory<>(producerProperties);
}
}
// ${base.dir}/app2/src/main/java/com/example/group/service/SomeService.java
package com.example.group.service;
/* Imports omitted */
@Service
public final class SomeServiceImpl implements SomeService {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeServiceImpl.class);
private final KafkaTemplate<Bytes, Object> kafkaTemplate;
private final String topic;
@Autowired
public SomeServiceImpl(
KafkaTemplate<Bytes, Object> kafkaTemplate,
@Value("${topic}") String topic) {
this.kafkaTemplate = kafkaTemplate;
this.topic = topic;
}
/* omitted */
}
This is bizarre and I cannot figure out why Spring keeps telling me it cannot find a KafkaTemplate bean. Even IntelliJ tells me that it cannot find an autowire candidate for KafkaTemplate.
Things I've tried
- Deleting my custom
@Beans, and relying onKafkaAutoConfiguration(it fails, saying it cannot find aProducerFactory) - Giving the
KafkaTemplatebean a name, and using@QualifierinSomeService - Moving the
@Beandefinitions around.
None of these have worked, and so I'm at my wits end. Any insights would be helpful.
Solution 1:[1]
So it turns out this was a case of PEBKAC (Problem exists between keyboard and chair).
The Bytes type in my config object referred to com.google.common.primitives.Bytes and the Bytes in my service class referred to org.apache.kafka.common.utils.Bytes.
Lesson to self:
Check your types.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Marley |
