#SpringbootApplication does not scan components in default package - spring

Hi I have my main class of spring boot app in package com
and two other beans defined in com.bbh.fx.pack1.
As per my understanding SpringBootApplication will autoscan all the components in its pakacge and childern package. But it is not scanning. Not sure what i am missing
**package com.bbh.fx.pack1;**
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
#Component
public class BeanA {
#PostConstruct
public void init() {
System.out.println("in BEANA");
}
}
**package com;**
#SpringBootApplication
public class MainApp{
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
}

You do not have a main in your MainApp your code should look like:
#SpringBootApplication
public class MainApp{
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
}
I usually like to start all new applications from https://start.spring.io/ you can choose your project name, build type (maven or gradle) and select any spring dependencies you'd like included in the application.

Use #ComponentScan to scan components.
#SpringBootApplication
#ComponentScan("com")
public class MainApp{
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
}

Related

Spring Boot integration testing with JUnit

package com.example.demo;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.out.println("Hello !");
// SpringApplication.run(DemoApplication.class, args);
SpringApplication application = new SpringApplication(DemoApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
And test
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
#SpringBootTest(classes = DemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class DemoApplicationTests {
#Test
void contextLoads() {
}
}
DemoApplicationTest seems to not use or be aware anythig about DemoApplication (#Spring BootApplication).
And I can't figure out if Maven project has multiple maven modules, how can they be included in test. Seem to me that Spring app does not even care about profiles defined in test.
Please point to relevant example or documentation: how to configure the test, so that it works like Spring Boot service where running on its own.
CommandLineRunner however gets executed also when running from test class:
#SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
System.out.println("Hello !");
// SpringApplication.run(DemoApplication.class, args);
SpringApplication application = new SpringApplication(DemoApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
#Autowired
ApplicationContext applicationContext;
#Override
public void run(String... args) throws Exception {
String[] beans = applicationContext.getBeanDefinitionNames();
Arrays.sort(beans);
for (String bean : beans) {
System.out.println(bean);
}
System.out.println(".............................");
}
}
But with Spring-banner .
First, add #ExtendWith(SpringExtension.class) to your test class.
Rest of the example, you can check here :
https://howtodoinjava.com/spring-boot2/testing/spring-boot-2-junit-5/

Spring does not find bean

I get the following error:
Field delegate in package.rest.api.MyApiController required a bean of type 'package.rest.api.MyApiDelegate' that could not be found.
I've tried to add annotation #ComponentScan("package.rest") to the main class, but it didn't help.
package package;
#SpringBootApplication
#Import(SpecificationConf.class)
//#ComponentScan("package.rest")
public class MyApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
package package.rest.api;
#Controller
#RequestMapping(...)
public class MyApiController implements MyApi {
#Autowired
#Qualifier("myService")
private MyApiDelegate delegate;
}
package package.rest;
#Service("myService")
public class MyApiDelegateImpl implements MyApiDelegate {
...
}
package package.rest.api;
public interface MyApiDelegate {
...
}
Can that problem happen due to incorrect configuration of the Application context or an inappropriate maven profile? I've tried to move classes to the same package, but it also didn't help.
Given that you are building a JAR file and not a WAR file, please try dropping SpringBootServletInitializer from your main class as follows:
package package;
#SpringBootApplication
#Import(SpecificationConf.class)
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}

#Converter(autoApply = true) not working in different package

This is under package: com.a.b
package com.a.b;
#Converter(autoApply = true)
public class DateConverter implements AttributeConverter<Date, String> {
}
application start class under package: com.a.c
package com.a.c;
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
in differnet package, autoApply = true not working, except custom LocalContainerEntityManagerFactoryBean. Are there other solutions
You have to use #EntityScan. I assume that your entities are in com.a.c. If this is not the case you have to set the correct package:
package com.a.c;
#SpringBootApplication
#EntityScan(basePackages = {"com.a.c", "com.a.b"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

ApplicationReadyEvent not listened to when declaring #ComponentScan for library package

#componentscan({"com.test.cloud"})
#SpringBootApplication
public class TestClass {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(TestClass.class, args);
}
}
public class TestClass2{
#eventlistener(ApplicationReadyEvent.class)
public void testMethod() {
.....
.....
}
}
Here if I remove #componentscan({"com.test.cloud"}) annotation then the testMethod is triggered. But when I use #componentscan({"com.test.cloud"}) then the testMethod is not triggered.
SpringBoot Version: 1.5.10.RELEASE
Worked by adding:
#componentscan({"com.test.cloud","com.example.demo"})

Spring batch with multiple main and scheduler

I am working on a Spring Batch project that has two Main classes with #SpringBootApplication in it. I also have to use the #Scheduler and associate it only with one Main class. But the issue here is no matter which class I run, the scheduler is getting executed. Snippets below,
MainApp1.java
#SpringBootApplication
#EnableScheduling
public class MainApp1{
public static void main(String[] args) {
SpringApplication.run(MainApp1.class, args);
}
}
MainApp2.java
#SpringBootApplication
public class MainApp2{
public static void main(String[] args) {
SpringApplication.run(MainApp2.class, args);
}
}
Scheduler.java
#Configuration
public class TmsBatchSenderScheduler {
#Scheduled(fixedDelay = 5000)
public void myScheduler() {
}
}
I think what's happening here is the scheduler is getting created for both mains because of the #Configuration annotation. Is there a way to achieve this? I want the scheduler to run only when the MainApp1 is run.
Thanks in advance :)

Resources