How to resolve @Inject that gives NullPointerException?

13,602

The problem is using the 'new' keyword to instantiate SubSectorToStockParser

@Model
public class StockUploadController {
 ...
    public void parse(String filename){

        Map<String, List<String>> subSectorToStockMap = new HashMap<>();
        SubSectorToStockParser parser = new SubSectorToStockParser(subSectorToStockMap);  //SubSectorToStockParser should be injected
        parser.parse(filename);

    }
...

By using the 'new' keyword, CDI has no control over the lifecycle of the resulting object and thus cannot perform injections, causing stockUploadController to be null.

To solve this, mark SubSectorToStockParser with the appropriate scope (e.g: @Model), then inject it into StockUploadController.

Share:
13,602

Related videos on Youtube

bencampbell_14
Author by

bencampbell_14

Software Developer and a Master of Data Science student.

Updated on June 04, 2022

Comments

  • bencampbell_14
    bencampbell_14 almost 2 years

    I have been looking for a possible solution why the @Inject object I'm using is returning null. I looked all over stackoverflow and I also bump into this site Solving @Inject and Null Pointer Exception and Im sure that Ive already taken those into consideration.

    I have a jsf file, sector.xhtml. I'm doing a file upload and calling the method upload of fileUploadController. Then the stockUploadController calls the parse method that calls the SubSectorStockParser's parse method. This method parses the uploaded csv, looping through each readline call. subSectorToStockMapping[4] is the sub sector value found in the csv file and it is being used to do a query to the database to retrieve the Subsector object. This is where the problem lies ---- the line ---

    Subsector subSector = stockUploadController.findSubsector(subSectorToStockMapping[4]);
    

    The stockUploadController is null eventhough it was annotated as @Inject, so it throws a NullPointerException.

    21:51:57,316 INFO  [stdout] (default task-20) stockUploadController:null
    21:51:57,316 ERROR [stderr] (default task-20) java.lang.NullPointerException
    21:51:57,317 ERROR [stderr] (default task-20)   at com.traderpau.app.util.SubSectorToStockParser.parse(SubSectorToStockParser.java:45)
    21:51:57,317 ERROR [stderr] (default task-20)   at com.traderpau.app.controller.StockUploadController.parse(StockUploadController.java:42)
    21:51:57,317 ERROR [stderr] (default task-20)   at com.traderpau.app.controller.StockUploadController$Proxy$_$$_WeldClientProxy.parse(Unknown Source)
    21:51:57,318 ERROR [stderr] (default task-20)   at com.traderpau.app.controller.FileUploadController.upload(FileUploadController.java:84)
    21:51:57,318 ERROR [stderr] (default task-20)   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    21:51:57,318 ERROR [stderr] (default task-20)   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    21:51:57,319 ERROR [stderr] (default task-20)   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    21:51:57,319 ERROR [stderr] (default task-20)   at java.lang.reflect.Method.invoke(Method.java:606)
    21:51:57,319 ERROR [stderr] (default task-20)   at com.sun.el.parser.AstValue.invoke(AstValue.java:292)
    21:51:57,320 ERROR [stderr] (default task-20)   at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
    21:51:57,320 ERROR [stderr] (default task-20)   at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    21:51:57,320 ERROR [stderr] (default task-20)   at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    21:51:57,321 ERROR [stderr] (default task-20)   at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    21:51:57,321 ERROR [stderr] (default task-20)   at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    21:51:57,321 ERROR [stderr] (default task-20)   at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    21:51:57,322 ERROR [stderr] (default task-20)   at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    

    I have confirmed that other parts of my code that uses @Inject is working.

    Can you offer any other things that I might have missed out or any things that I can investigate to resolve this problem?

    WEB-INF/beans.xml

     <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="
                http://xmlns.jcp.org/xml/ns/javaee
                http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
        </beans>
    

    sector.xhtml

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:p="http://primefaces.org/ui"> 
    
    <h:head>
    <title>Sector Test Entry</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <h:outputStylesheet name="css/screen.css" />
    </h:head> 
    <h:body> 
        <ui:composition template="/template/common/commonLayout.xhtml">
            <ui:define name="content">
        <div id="content">
            <h:form id="transaction" enctype="multipart/form-data">
            <p:growl id="growl" life="2000" />
                <p:panelGrid columns="2">
    
                    <p:outputLabel value="Update:"/>
                    <h:selectOneRadio id="update" value="#{dataUpdateBean.updateOption}">
                        <f:selectItem noSelectionOption="true" itemLabel="Sector" itemValue="Sector"/>
                        <f:selectItem itemLabel="Sub to Stocks" itemValue="Stocks"/>                    
                    </h:selectOneRadio>
                    <h:outputText value="&#160;" />
                    <p:fileUpload id="file" value="#{fileUploadController.file}" mode="simple" />
    
                    <h:commandButton action="#{fileUploadController.upload}" 
                        value="Click Me" />
    
    
                </p:panelGrid>
            </h:form>
    
        </div>
        </ui:define>
        </ui:composition>
    </h:body> 
    </html>
    

    FileUploadController.java

    import java.text.SimpleDateFormat;
    
    import javax.enterprise.inject.Model;
    import javax.faces.application.FacesMessage;
    import javax.faces.context.FacesContext;
    import javax.inject.Inject;
    import javax.servlet.http.Part;
    
    import org.primefaces.event.FileUploadEvent;
    import org.primefaces.model.UploadedFile;
    
    import com.traderpau.app.data.DataUpdateBean;
    
    @Model
    public class FileUploadController {
    
        @Inject
        private SectorUploadController sectorUploadController;
    
        @Inject 
        private StockUploadController stockUploadController;
    
        @Inject 
        private DataUpdateBean updateBean;
    
        private UploadedFile file;
    
        private Part filePart;
    
    
        public Part getFilePart() {
            return filePart;
        }
    
    
        public void setFilePart(Part filePart) {
            this.filePart = filePart;
        }
    
    
        public UploadedFile getFile() {
            return file;
        }
    
    
        public void setFile(UploadedFile file) {
            this.file = file;
        }
    
        public void saveFile(){
            System.out.println("File:" + file);
            System.out.println("File part:" + 
            filePart);
        }
    
    
        @SuppressWarnings("unused")
        public void upload() throws Exception{
            String fileName = file.getFileName();
    
            if(file != null) {
                FacesMessage message = new FacesMessage("Succesful", fileName + " is uploaded.");
                FacesContext.getCurrentInstance().addMessage(null, message);
            }else{
                FacesMessage message = new FacesMessage("Error in upload of " + fileName );
                FacesContext.getCurrentInstance().addMessage(null, message);
            }
            String path = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
            SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
            if(updateBean.getUpdateOption().equalsIgnoreCase("Sector")){
                file.write(
                        String.format("%s%s%s", path, "_TRADE_MONITOR_UPLOAD/SECTOR_TO_SUB/",fileName
                                ));
                sectorUploadController.parse(String.format("%s%s%s", path, "_TRADE_MONITOR_UPLOAD/SECTOR_TO_SUB/",fileName
                        ));
                FacesMessage message = new FacesMessage("Sector to Sub successdul.");
                FacesContext.getCurrentInstance().addMessage(null, message);
            }else if(updateBean.getUpdateOption().equalsIgnoreCase("Stocks")){
                file.write(
                        String.format("%s%s%s", path, "_TRADE_MONITOR_UPLOAD/SUB_TO_STOCK/",fileName
                                ));
                stockUploadController.parse(String.format("%s%s%s", path, "_TRADE_MONITOR_UPLOAD/SUB_TO_STOCK/",fileName));
                FacesMessage message = new FacesMessage("Sub to Stocks successful.");
                FacesContext.getCurrentInstance().addMessage(null, message);
            }
        }
    }
    

    StockUploadController.java

    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.enterprise.inject.Model;
    import javax.faces.application.FacesMessage;
    import javax.faces.context.FacesContext;
    import javax.faces.event.ActionEvent;
    import javax.inject.Inject;
    
    import com.traderpau.app.data.DataUpdateBean;
    import com.traderpau.app.model.Stock;
    import com.traderpau.app.model.Subsector;
    import com.traderpau.app.service.StockRegistration;
    import com.traderpau.app.util.SubSectorToStockParser;
    
    @Model
    public class StockUploadController {
        @Inject
        private StockRegistration stockRegistration;
    
        @Inject
        private DataUpdateBean bean;
    
        public void findSubsectorName(ActionEvent actionEvent){
            addMessage("Search query:" + bean.getSubSectorName());
            System.out.println("StockUploadController:findSubsectorName");
            stockRegistration.findSubSectorName(bean.getSubSectorName());
        }
    
        public void addMessage(String summary) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary,  null);
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    
        public void parse(String filename){
    
            Map<String, List<String>> subSectorToStockMap = new HashMap<>();
            SubSectorToStockParser parser = new SubSectorToStockParser(subSectorToStockMap);
            parser.parse(filename);
    
        }
    
        public Subsector findSubsector(String name){
            System.out.println("StockRegistration:" + stockRegistration);
            return stockRegistration.findSubSectorName(name);
        }
    
        public void registerStock(Stock stock) throws Exception{
            stockRegistration.register(stock);
        }
    
    }
    

    SubSectorToStockParser.java

        import java.io.BufferedReader;
        import java.io.FileNotFoundException;
        import java.io.FileReader;
        import java.io.IOException;
        import java.util.HashMap;
        import java.util.List;
        import java.util.Map;
    
        import javax.inject.Inject;
    
        import com.traderpau.app.controller.StockUploadController;
        import com.traderpau.app.model.Stock;
        import com.traderpau.app.model.Subsector;
        import com.traderpau.app.service.StockRegistration;
    
         public class SubSectorToStockParser implements Parser {
    
        private Map<String, List<String>> subSectorToStockMap = new HashMap<>();
    
        @Inject
        private StockRegistration stockRegistration;
    
        @Inject
        private StockUploadController stockUploadController;
    
        public SubSectorToStockParser(Map<String, List<String>> subSectorToStockMap) {
            super();
            this.subSectorToStockMap = subSectorToStockMap;
        }
    
        @Override
        public void parse(String filename) {
            System.out.println("Sub sector filename:" + filename);
            BufferedReader br = null;
            try{
                br = new BufferedReader(new FileReader(filename));
                String line;
                String csvSplitBy = ",";
                System.out.println("stockUploadController:" + stockUploadController );
    
                while((line = br.readLine()) != null){
                    String[] subSectorToStockMapping   = line.split(csvSplitBy);
                    Subsector subSector = stockUploadController.findSubsector(subSectorToStockMapping[4]);
                    Stock stock = new Stock();
                    stock.setSymbol(subSectorToStockMapping[0]);
                    stock.setStockName(subSectorToStockMapping[1]);
                    stock.setOutstandingShares( Double.parseDouble(subSectorToStockMapping[2]) );
                    stock.setSubSector(subSector != null? subSector: null);
                    stockUploadController.registerStock(stock);
                }
    
            }catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }
    
    • Kukeltje
      Kukeltje over 8 years
      is this the whole stacktrace?
  • Kukeltje
    Kukeltje about 7 years
    Isn't this exactly what is mentioned in the other answer?