1

i have created a simple java class in spring boot application. calling a method ns.mesage(); from two different methods but one is executed and another one throw an null pointer exception.

package TestPackage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/*
import TestPackage.MorningService;
import TestPackage.NightService;*/

@RestController
public class GenerateMessage {


    @Autowired
    public MorningService ms;

    @Autowired
    public NightService ns;



    @RequestMapping(path = "/test")
    public String starter(){
        GenerateMessage gm=new GenerateMessage();
        ns.mesage(); // this call working fine

        gm.mes();
        return "Mail scheduled.";
    }




public void mes(){
    try{
    System.out.println("starts2..............");
    ns.mesage(); // throwing an exception
    }catch(Exception e){
        e.printStackTrace();
    }
}
}
2
  • Please post full stack trace and please follow appropriate naming, gm, ns are not valid names, use nightService and morningService instead. Commented Feb 18, 2020 at 6:55
  • where are your dependencies defined? Commented Feb 19, 2020 at 5:26

3 Answers 3

4

Once you're using the new keyword, you're breaking all the injections used with @Autowired(it means that the MorningService and NightService will not be initialized) , that is why you're getting a NPE.

If you really want to test your mes() method from your controller, implement in your @SpringBootApplication class the CommandLineRunner interface.

Then you can inject a GenerateMessage bean with @Autowired and test your method.

Here is an example:

@SpringBootApplication
public class MainApplication implements CommandLineRunner {

 @Autowired
 private GenerateMessage generateMessage;

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

 @Override
 public void run(String... args) throws Exception {
    generateMessage.mes();
 }
}
Sign up to request clarification or add additional context in comments.

Comments

2

You must not mix usage of new with Autowired.

Once you're using the new keyword, you're breaking all the injections used with @Autowired(it means that the MorningService and NightService will not be initialized) , that is why you're getting a NPE.

Soulution No.1

use AUTOWIRE

@Autowired
public MorningService ms;

@Autowired
public NightService ns;

@Autowired
GenerateMessage gm;

@RequestMapping(path = "/test")
public String starter(){
//        GenerateMessage gm=new GenerateMessage();
    ns.mesage(); // this call working fine

    gm.mes();
    return "Mail scheduled.";
}

Solution No.2

use this keyword

@RequestMapping(path = "/test")
public String starter(){
//        GenerateMessage gm=new GenerateMessage();
    ns.mesage(); // this call working fine

    this.mes();
    return "Mail scheduled.";
}

Comments

0

When you create an instance with keyword new, it doesn't go through the spring bean lifecycle. In a result post-processor, which response for processing @Autowired annotation doesn't work, and NightService not injected in new instance of GenerateMessage. You just create an instance of the class with null fields.

If you want to create real bean manually you should do it like this:

@RestController
public class GenerateMessage {


    @Autowired
    public MorningService ms;

    @Autowired
    public NightService ns;

    @Autowired
    private ApplicationContext applicationContext;

    @RequestMapping(path = "/test")
    public String starter(){
        GenerateMessage gm=applicationContext.getBean(GenerateMessage.class);
        ns.mesage(); // this call working fine

        gm.mes();
        return "Mail scheduled.";
    }




public void mes(){
    try{
    System.out.println("starts2..............");
    ns.mesage(); // throwing an exception
    }catch(Exception e){
        e.printStackTrace();
    }
}
}

But I do not recommend you to work with the applicationcontext directly, cause it is a heavy object and may lead to decrease performance.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.