-1

So I'm using Spring to generate random stories and I am getting a NullPointerException on line 73 of the controller which is where I call the ApplicationContext to make a BeanFactory in the function that gets the beans (MadLib and PartOfSpeech classes) from text files. The context was working just fine before I added that function. What's wrong?

Edit: I do know what a NullPointerException is. I don't know why it's happening here. Also, it works when I comment out the constructor. I think the problem might be that I'm trying to call the context before it exists?

Edit 2: I tried moving the call to getBeansFromFiles() to the first GetMapping(links). This took away the NullPointerException, probably because the Controller bean had already been initialized, so the context existed. But while the MadLibs got added to the list, the beans were not created or at least not autowired. Is there a place I can put this call where both will work? Do I need to implement an interface that will make this call at the right time?

package controllers;

import...


@Controller
@RequestMapping(value = "/madLib")
public class MadLibController {
    @Autowired
    ApplicationContext context;

    public MadLibController(){
        getBeansFromFiles();
    }

    public PartOfSpeech pos(String path){
        String input;
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v";
        }
        return new PartOfSpeech(input);
    }

    public MadLib ml(String path){
        String input;
        System.out.println(new File("").getAbsolutePath());
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v#V#v";
        }
        return new MadLib(input);
    }

    public void getBeansFromFiles() {
        AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();
        File folder = new File("../../txt/ml");
        File[] listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            MadLib ml = ml(file.getPath());
            String beanName = ml.getId();
            beanFactory.autowireBean(ml);
            beanFactory.initializeBean(ml, beanName);
            ((MadLibList)context.getBean("madLibList")).getList().add(ml);
        }
        folder = new File("../../txt/pos");
        listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            PartOfSpeech pos = pos(file.getPath());
            String beanName = pos.getId();
            beanFactory.autowireBean(pos);
            beanFactory.initializeBean(pos, beanName);
        }
    }

    /*@Bean("verb")
    public PartOfSpeech verb(){
        return pos("verb");
    }

    @Bean("hansel2")
    public MadLib hansel2(){
        return ml("hansel");
    }

    @Bean("lunch")
    public MadLib lunch(){
        return ml("lunch");
    }*/



    @GetMapping
    public String links(Model model){
        MadLibList list = (MadLibList)context.getBean("madLibList");
        //list.getList().add(hansel2());
        //list.getList().add(lunch());
        model.addAttribute("madLibList", list);
        return "madLibLinks";
    }

    @GetMapping("/{name}")
    public String prompts(HttpServletRequest req, HttpServletResponse res, 
            Model model, @PathVariable("name") String name, 
            @RequestParam(value = "random", defaultValue = "false") String random){
        MadLib madLib = (MadLib)context.getBean(name);
        madLib.setAnswers(new ArrayList<String>(madLib.getPrompts().size()));
        System.out.println("Answers: " + madLib.getAnswers());
        if (random.equals("true")){
            System.out.println("Prompts: " + madLib.getPrompts());
            for (int i=0; i<madLib.getPrompts().size(); i++){
                try {
                    String posBean = utility.Util.camelCase(madLib.getPrompts().get(i));
                    PartOfSpeech pos = (PartOfSpeech)context.getBean(posBean);
                    String word = pos.getWord();
                    System.out.println(word);
                    madLib.getAnswers().add(word);
                } catch (Exception e) {
                    System.out.println("exception in randomizing answers for " + madLib.getPrompts().get(i));
                    System.out.println(e);
                    madLib.getAnswers().add("");
                }
            }
        }
        model.addAttribute("default", "");
        model.addAttribute("madLib", madLib);
        return "madLibPrompts";
    }

    @PostMapping(value = "/result")
    public String result(Model model, @ModelAttribute("madLib") MadLib madLib, BindingResult result){
        System.out.println(madLib.getAnswers().get(0));
        //model.addAttribute(madLib);
        return "madLibResult";
    }



}

1 Answers1

0

Implement BeanDefinitionRegistryPostProcessor and use beanFactory instead of context

package controllers;

import...

@Controller
@RequestMapping(value = "/madLib")
public class MadLibController implements BeanDefinitionRegistryPostProcessor {
    @Autowired
    ApplicationContext context;

    ConfigurableListableBeanFactory beanFactory;

    private BeanDefinitionRegistry registry;

    public PartOfSpeech pos(String path){
        String input;
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v";
        }
        return new PartOfSpeech(input);
    }

    public MadLib ml(String path){
        String input;
        System.out.println(new File("").getAbsolutePath());
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v#V#v";
        }
        return new MadLib(input);
    }

    public void getBeansFromFiles() {
        File folder = new File("../../txt/ml");
        File[] listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            MadLib ml = ml(file.getPath());
            String beanName = ml.getId();
            beanFactory.registerSingleton(beanName, ml);
            ((MadLib)beanFactory.getBean(beanName)).setId(ml.getId());
            ((MadLib)beanFactory.getBean(beanName)).setTitle(ml.getTitle());
            ((MadLib)beanFactory.getBean(beanName)).setAnswers(ml.getAnswers());
            ((MadLib)beanFactory.getBean(beanName)).setPrompts(ml.getPrompts());
            ((MadLib)beanFactory.getBean(beanName)).setStrings(ml.getStrings());
            ((MadLibList)beanFactory.getBean("madLibList")).getList().add(ml);
        }
        folder = new File("../../txt/pos");
        listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            PartOfSpeech pos = pos(file.getPath());
            String beanName = pos.getId();
            beanFactory.registerSingleton(beanName, pos);
            ((PartOfSpeech)beanFactory.getBean(beanName)).setName(pos.getName());
            ((PartOfSpeech)beanFactory.getBean(beanName)).setWords(pos.getWords());
        }
    }


    @GetMapping
    public String links(Model model){
        MadLibList list = (MadLibList)beanFactory.getBean("madLibList");
        model.addAttribute("madLibList", list);
        return "madLibLinks";
    }

    @GetMapping("/{name}")
    public String prompts(HttpServletRequest req, HttpServletResponse res, 
            Model model, @PathVariable("name") String name, 
            @RequestParam(value = "random", defaultValue = "false") String random){
        MadLib madLib = (MadLib)beanFactory.getBean(name);
        //System.out.println(madLib);
        madLib.setAnswers(new ArrayList<String>(madLib.getPrompts().size()));
        System.out.println("Answers: " + madLib.getAnswers());
        if (random.equals("true")){
            System.out.println("Prompts: " + madLib.getPrompts());
            for (int i=0; i<madLib.getPrompts().size(); i++){
                try {
                    String posBean = utility.Util.camelCase(madLib.getPrompts().get(i));
                    PartOfSpeech pos = (PartOfSpeech)beanFactory.getBean(posBean);
                    String word = pos.getWord();
                    System.out.println(word);
                    madLib.getAnswers().add(word);
                } catch (Exception e) {
                    System.out.println("exception in randomizing answers for " + madLib.getPrompts().get(i));
                    System.out.println(e);
                    e.printStackTrace();
                    madLib.getAnswers().add("");
                }
            }
        }
        model.addAttribute("default", "");
        model.addAttribute("madLib", madLib);
        return "madLibPrompts";
    }

    @PostMapping(value = "/result")
    public String result(Model model, @ModelAttribute("madLib") MadLib madLib, BindingResult result){
        System.out.println(madLib.getAnswers().get(0));
        //model.addAttribute(madLib);
        return "madLibResult";
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
        this.beanFactory = arg0;
        getBeansFromFiles();
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry arg0) throws BeansException {
        this.registry = arg0;
    }



}