如何解决给出NullPointerException的@Inject?

时间:2015-08-26 13:42:02

标签: java jsf nullpointerexception cdi inject

我一直在寻找一个可能的解决方案,为什么我正在使用的@Inject对象返回null。我遍布stackoverflow,我也碰到了这个网站Solving @Inject and Null Pointer Exception 我确信我已经考虑到了这些。

我有一个jsf文件,sector.xhtml。我正在上传文件并调用fileUploadController的方法上传。然后stockUploadController调用调用 SubSectorStockParser的解析方法的parse方法。此方法解析上传的csv,循环遍历每个readline调用。 subSectorToStockMapping [4]是在csv文件中找到的子扇区值,它用于对数据库进行查询以检索Subsector对象。这就是问题所在 - 线---

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

stockUploadController是null,因为它被注释为@Inject,所以它会抛出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)

我已经确认使用@Inject的代码的其他部分正在运行。

您能否提供我可能遗漏的任何其他内容或我可以调查以解决此问题的任何内容?

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();
                }
            }
        }
    }

}

1 个答案:

答案 0 :(得分:0)

根据我的经验,问题出在

SubSectorToStockParser parser = new SubSectorToStockParser(subSectorToStockMap);

使用容器托管bean时,我们不应该使用new来实例化ant bean / class。 你我在这里做的只是使用构造函数注入或setter注入将SubSectorToStockParser注入bean。这将使SubSectorToStockParser由容器管理。