Anirban
Anirban

Reputation: 949

Spring boot application not starting

I am trying to get started with building a REST application with Spring boot.

My pom looks as below:

<?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>com.example</groupId>
    <artifactId>SpringBootDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SpringBootDemo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

My starter class looks as below:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootDemoApplication {

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

My controller class looks as below:

package com.example.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/greeting")
public class GreetingController {

    @RequestMapping("/greet")
    public String greet() {
        return "hello";
    }

}

When I am building the file using maven and then running the application in embedded tomcat and then trying to access the url localhost:8080/greeting/greet, it is giving me error page. Can anyone guild me what I am doing wrong?

Upvotes: 0

Views: 11935

Answers (2)

Alexandre Hamon
Alexandre Hamon

Reputation: 1402

I had a hard time trying to make it work. Here is a resume of what was necessary to make it work on my project :

1/ You need a dependency to an embedded server :

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <version>${spring-boot-dependencies.version}</version>
            </dependency>

2/ For the embedded server to start, you need Spring to find a working Controller under the same package of your @SpringBootApplication

For instance if your @SpringBootApplication is in package com.myapp.package, you could put a controller in com.myapp.package.controller :

package com.myapp.package.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.function.Consumer;

@RestController
public class HelloController implements Consumer<String> {

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index() {
        return "Greetings from Spring Boot!";
    }

    @Override
    public void accept(String s) {

    }
}

Make sure to try with theses annotations somewhere (@RestController and @RequestMapping) because I was using wrong ones first and I lost a lot of time !

NOTE 1: If you want your controller in another package, you can had this to your @SpringBootApplication :

@SpringBootApplication(scanBasePackages = {""com.myapp.package"", "com.myapp.packagebis"})

NOTE 2: I also saw people having problem with maven dependency going wrong, seems like some people succeded in doing it work cleaning maven dependencies using mvn dependency:purge-local-repository

Helpers :

You can had this to your @SpringBootApplication to see all Spring Beans :

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {

            System.out.println("Let's inspect the beans provided by Spring Boot:");

            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                System.out.println(beanName);
            }

        };
    }

Upvotes: 0

ikos23
ikos23

Reputation: 5354

Your main class is inside com.example.demo package. It means when you start your Spring Boot application it will scan that package and all the nested packages to find Spring components and register them.

So, basically auto scanning will check those:

com.example.demo
com.example.demo.something
com.example.demo.somethingelse

Your controller class is in com.example.controller which means it won't be founded.

You could either move it to something like com.example.demo.controller or tell Spring where it should find its components :

@SpringBootApplication(scanBasePackages = {"com.example.controller"})

A good practice is to have your main class in kinda root package and everything else in nested packages. Here is an example:

com.example.demo // main class here
com.example.demo.controller
com.example.demo.service
com.example.demo.repository
....

Then Spring can find everything automatically and you won't need to configure it manually.

Upvotes: 2

Related Questions