Spring application does not start outside of a package

I am following this tutorial to build a basic application with Spring. It is working flawlessly as long as I follow this sub-directory structure:

└── src
    └── main
        └── java
            └── hello

If I move my Application.java and ScheduledTasks.java classes out of the hello package I get the following error:

** WARNING ** : Your ApplicationContext is unlikely to start due to a `@ComponentScan` of the default package.

And a few seconds later, indeed...

java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext@71fa8894: startup date [Wed Jan 18 22:19:12 CET 2017]; root of context hierarchy

My question is, why do I need to put my classes into a package? What use does it have? How can I avoid this error? Do I really need to use packages if it is a really simple application?


Solution 1:

Put your java files again to hello package.

When a class doesn’t include a package declaration it is considered to be in the “default package”. The use of the “default package” is generally discouraged, and should be avoided.

It can cause particular problems for Spring Boot applications that use @ComponentScan, @EntityScan or @SpringBootApplication annotations, since every class from every jar, will be read.

Read more here.

Solution 2:

I moved the class annotated with @SpringBootApplication from the default package to a specific package and it worked.

Solution 3:

I had created a blank Maven folder where Java folder was the last one. I added class MainApplication.

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


@SpringBootApplication
public class MainApplication {

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

    }
}

Further, I had to create a package within Java folder such as com.test and then I moved my MainApplication class into it. Note "package com.test;" Now this default package Spring boot is looking for.

package com.test;

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

@SpringBootApplication
public class MainApplication {

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

    }
}

Then it worked fine.