0

I switched from getting values by loading up the properties file and retrieve them to using @Value annotations. Right now I am able to print the values that I set. When I run my application I see the value, But when I open up localhost:8080 I receive a null exception.

IndexController

@Controller
public class IndexController {
     @RequestMapping(value = "/", method = RequestMethod.GET)
     public ModelAndView getdata() throws IOException {
        AppPortList apL = new AppPortList();
        List<AppPortModel> apList = apL.getAppPortList();   
        Collections.sort(apList);

ModelAndView model = new ModelAndView("index");
    model.addObject("showap", apList);

    return model;
}

Properties file

APP_SERVERS=Server1@!Server1212@!Server12daa21@!Server21334
APP_SERVER_List=1020@!3011@!8080@!2020

//much more servers than this.

Class that is having errors

@Component
public class AppPortList {      

 @Value("#{'${APP_SERVERS}'.split('@!')}")
    private String[] apServerArray;
 @Value("#{'${APP_SERVER_List}'.split('@!')}")
    private String[] appServerPortsList;

@PostConstruct
public List<AppPortModel> getAppPortList() {
    try {
        System.out.println(apServerArray.length + "@@@@");
            for (int z = 0; z < apServerArray.length; z++) {                
                String apServer = apServerArray[z];
                String[] portListArray=appServerPortsList;
}catch {//stuff}

Console Output

16@@@@@

When I open local host I receive a null exception on Line 80. Which is my for Statement. "for (int z = 0; z < apServerArray.length; z++)" is coming up null.

Running local Host Error

  java.lang.NullPointerException: null
at com.spring.web.util.AppPortList.getAppPortList(AppPortList.java:82) ~[classes/:na]
    at com.spring.web.controller.IndexController.getdata(IndexController.java:61) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_91]

Attempt 2

So I commented my for statment out and used System.out.println(apServerArray + "@@@@");

Output 2

 [Ljava.lang.String;@328b8745@@@@@

and when I ran my localhost I get null. So why does my console reads it when I run it then when I open localhost it becomes null?

  null@@@@@
7
  • try with ${APP_SERVERS:} (add : before the closing accolade). Does it changes the behavior ? Commented Dec 6, 2016 at 21:52
  • No, same behavior. Commented Dec 6, 2016 at 21:53
  • Can you show how it is in your property file? Commented Dec 6, 2016 at 21:54
  • Also, my guess apServerArray and appServerPortsList should be of type List<String> Commented Dec 6, 2016 at 21:57
  • When I switch to List<String>. it won't even print to console. Commented Dec 6, 2016 at 22:03

1 Answer 1

1

You're seeing two things here:

You annotated AppPortList with @Component, so when you start your application, your beans are created by the Spring container and the @PostConstruct is called. When a bean is created by Spring, it also injects values for the @Value annotations, so that's why you see the correct output in the System.out.println() inside your @PostConstruct.

However, in your controller you are using new AppPortList(). In this case you created the beans by yourself and you're not using the bean offered by the Spring container. In this case, the @Value annotation is not picked up, so the output is null.

The solution is simple, rather than using the new keyword, you have to use dependency injection. When you use dependency injection, the Spring container will look for an instance of the bean (which is has thanks to the @Component annotation) and it will inject it where you need it.

In your case you need it in your IndexController, so you'll have to change it a bit:

@Controller
public class IndexController {
    @Autowired
    private AppPortList apL; // Create this field with @Autowired annotation

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView getdata() throws IOException {
        // Remove new AppPortList() and use field in stead
        List<AppPortModel> apList = apL.getAppPortList();   
        // ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I really have to avoid using "new".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.