0

I am developing a spring boot application to send sms notification. This is my class for the purpose.

package org.otp.services;

import org.otp.Configurations;
import com.mashape.unirest.http.HttpResponse;
import org.springframework.stereotype.Component;

import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;

@Component
public class SmsService
{
    private static final Logger LOG = LoggerFactory.getLogger(SmsService.class);

    public String send(String mobile, String msg)
    {
        //Code 
    }
}

And this is the class which uses the above class for sending notification.

package org.otp.controllers;

import org.otp.Constants;
import org.otp.services.EmailService;
import org.otp.services.SmsService;
import org.otp.dto.MessageRequest;
import org.otp.dto.MessageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

@Component
public class MessageController {

    private static final Logger LOG = LoggerFactory.getLogger(MessageController.class);

    @Autowired
    SmsService smsService;

    public void sendMessageToAlert(@RequestBody MessageRequest messageRequest)
    {
        String smsStatus = "FAIL";
        MessageResponse messageResponse = new MessageResponse();

         //1. Nullpointer
        smsStatus = smsService.send(messageRequest.getMobileNo(),messageRequest.getMessage());

    }
}

Main Class

package org.otp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class OtpServiceApplication implements ApplicationRunner
{
    public static void main(String[] args) {
        SpringApplication.run(OtpServiceApplication.class, args);
    }
}

Problem is, I get a nullpointer exception in the (1) stating that my SmsService object is null. And my main class is in package org.otp so the two classes here falls under sub package so no need of component scan.

Therefore I am confused what to do to solve this. I have tried many answers here like adding a @Component annotation and @ComponentScan in main class but nothing works. Could someone please point out my mistake here.

Thanks in advance.

Ran_Macavity
  • 154
  • 2
  • 21

3 Answers3

1

If your @Autowired annotation is not working and throws NPE ,it means that spring fails to create an instance of the component class in the application context . Try to:

  • Verify that the classes are in class path for scanning and also check to ensure that all auto-wired classes have the annotation @Component to enable them to be picked up during class path scanning.
  • Check the spring boot start up logs to verify if there are any errors during bean creation.
  • Check to ensure all related classes used in the service layer are auto-wired properly and that the injected classes are annotated with @Component .

For further help please share the main application class along with your project structure.


Since you are using springboot , it is preferable to use the sprinboot stereotype annotations instead of the @Component annotation, if you are building a standard springboot web application.

  • @Service : for the service layer.
  • @Controller : for the controller layer . Also,DispatcherServlet will look for @RequestMapping on classes which are annotated using @Controller but not with @Component.
Ananthapadmanabhan
  • 5,706
  • 6
  • 22
  • 39
-1

In Springboot application's main class add following annotation

@SpringBootApplication
@ComponentScan(
    basePackages = {"org.otp.*"}
)
public class YourSpringMainClass{
  public static void main(String[] args) {
    SpringApplication.run(YourSpringMainClass.class, args);
  }
}
phanigo
  • 59
  • 8
  • Spring Boot adds that automatically and if you follow the guidelines, as the asker did, you don't need `@ComponentScan`. – M. Deinum Nov 11 '19 at 07:09
-1

While using annotations we should configured with @ComponentScan annotation to tell Spring the packages to scan for annotated components. This should be used in mail class(Which class wants to load first) in your case you are working with spring boot so you should use this annotation in Springboot application's main class. Like below

@SpringBootApplication
@ComponentScan(
    basePackages = {"org.otp.*"}
)
public class YourSpringMainClass{
  public static void main(String[] args) {
    SpringApplication.run(YourSpringMainClass.class, args);
  }
}
sreenu
  • 11
  • Spring Boot adds that automatically and if you follow the guidelines, as the asker did, you don't need `@ComponentScan`. – M. Deinum Nov 11 '19 at 07:09