Application Failed to Start Spring Boot

Justin :

I have one framework using Spring Boot which contains a controller RestController class ,

@RequestMapping("/details")
@RestController
public class DataController {
    private KafkaStreams kafkaStreams;

    public DataController(KafkaStreams kafkaStreams) {
        this.kafkaStreams = kafkaStreams;
    }

    @Autowired
    DataService dataService;

    @RequestMapping(value = "getAllDetails", method = RequestMethod.GET)
    public boolean getAllDetails(KafkaStreams kafkaStreams) {
        return ktableService.getAllDetails(kafkaStreams);
    }
}

In my service implementation class I am using this kafkaStreams object to find the details for my different services.

Now I am using this framework as a dependency in my one of the other application where I have a runner class,

import org.apache.kafka.streams.KafkaStreams;
@Component
public class PipelineRunner {
    private final StreamsBuilder streamsBuilder;
    private final KafkaProperties kafkaProperties;
    private final SerdesExt serdesExt;

    @Autowired
    public PipelineRunner(StreamsBuilder streamsBuilder, KafkaProperties kafkaProperties, SerdesExt serdesExt) {
        this.streamsBuilder = streamsBuilder;
        this.kafkaProperties = kafkaProperties;
        this.serdesExt = serdesExt;
    }

    @PostConstruct
    public void run() {
        ReflectData.AllowNull.get().addStringable(Utf8.class);
        ReflectData.get().addStringable(Utf8.class);
        DataProcessor processor = new DataProcessor(streamsBuilder, kafkaProperties,
                serdesExt);
        start();
    }

    private void start() {
        KafkaStreams kafkaStreams = new KafkaStreams(streamsBuilder.build(),
                kafkaProperties.getKafkaStreamsProperties(serdesExt));
        System.out.println("----Its is started----");
        DataController controller = new DataController(kafkaStreams);
        kafkaStreams.start();

    }
}

In this class i am trying to create the object for DataController .

So when I am trying to run the application class,

@SpringBootApplication(scanBasePackages = { "framework package" })
@EnableConfigurationProperties(KafkaProperties.class)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

I am getting this error,

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in frameworkpackage.controllers.DataController required a bean of type 'org.apache.kafka.streams.KafkaStreams' that could not be found.


Action:

Consider defining a bean of type 'org.apache.kafka.streams.KafkaStreams' in your configuration.

I am new to Spring Boot. So I might be doing something wrong here. If more info is needed I can provide.

UPDATE

My pom file,

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
    </parent>

    <properties>
        <confluent.version>4.1.0</confluent.version>
        <kafka.version>1.1.0</kafka.version>
        <lombok.version>1.18.0</lombok.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.confluent</groupId>
            <artifactId>kafka-avro-serializer</artifactId>
            <version>${confluent.version}</version>
        </dependency>
        <dependency>
            <groupId>io.confluent</groupId>
            <artifactId>kafka-streams-avro-serde</artifactId>
            <version>${confluent.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-streams</artifactId>
            <version>${kafka.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>${kafka.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-avro</artifactId>
            <version>2.8.5</version>
        </dependency>

    </dependencies>
Pavel Gordon :

A problem is that you are trying to use a bean kafkaStreams in your class DataController, but there is no bean with this name in Spring context. You need to create it manually, so you can autowire it later.

In your case I would suggest to update PipelineRunner.java like this:

import javax.annotation.PostConstruct;
import org.apache.kafka.streams.KafkaStreams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class PipelineRunner
{
    private final StreamsBuilder streamsBuilder;
    private final KafkaProperties kafkaProperties;
    private final SerdesExt serdesExt;


    @Autowired
    public PipelineRunner(StreamsBuilder streamsBuilder, KafkaProperties kafkaProperties, SerdesExt serdesExt)
    {
        this.streamsBuilder = streamsBuilder;
        this.kafkaProperties = kafkaProperties;
        this.serdesExt = serdesExt;
    }


    @PostConstruct
    public void run()
    {
        ReflectData.AllowNull.get().addStringable(Utf8.class);
        ReflectData.get().addStringable(Utf8.class);
        DataProcessor processor = new DataProcessor(streamsBuilder, kafkaProperties,
            serdesExt);
        start();
    }


    @Bean
    KafkaStreams kafkaStreams()
    {
        KafkaStreams kafkaStreams = new KafkaStreams(
            streamsBuilder.build(),
            kafkaProperties.getKafkaStreamsProperties(serdesExt));
        System.out.println("----Its is started----");
        kafkaStreams.start();
        return kafkaStreams;
    }
}

You dont need to create an instance of DataController by yourself, this will be done automatically by Spring.

More information about Spring approach to beans is available there

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=99863&siteId=1