2017-04-17 83 views
0

Glassfish日誌中報告的NullPointerException來自哪裏? ConverterServlet似乎有dollar作爲BigInteger號碼,非空。如果ConverterBean只是簡單地記錄美元的數額,那至少是朝着正確方向邁出的一步。也許EJB沒有被正確注入?從EJB注入到servlet的NullPointerException

硬編碼的金額是正確輸出:

什麼量?在 /ConverterApplication戰量的Servlet ConverterServlet爲999

美元:999類java.math.BigDecimal

但日元和歐元,因爲NPE的是從來沒有執行報告Glassfish的:

[2017-04-17T00:12:27.609-0700] [glassfish 4.1] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=84 _ThreadName=http-listener-1(1)] [timeMillis: 1492413147609] [levelValue: 900] [[ 
    StandardWrapperValve[ConverterServlet]: Servlet.service() for servlet ConverterServlet threw exception 
java.lang.NullPointerException 
    at net.bounceme.dur.ejb.ConverterServlet.processRequest(ConverterServlet.java:41) 
    at net.bounceme.dur.ejb.ConverterServlet.doGet(ConverterServlet.java:70) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) 
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) 
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111) 
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536) 
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) 
    at java.lang.Thread.run(Thread.java:745) 
]] 

的servlet:

package net.bounceme.dur.ejb; 

import java.io.IOException; 
import java.io.PrintWriter; 
import java.math.BigDecimal; 
import javax.ejb.EJB; 
import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

@WebServlet(urlPatterns = "/") 
public class ConverterServlet extends HttpServlet { 

    @EJB 
    ConverterBean converter; 

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 
     try (PrintWriter out = response.getWriter()) { 
      /* TODO output your page here. You may use following sample code. */ 
      out.println("<!DOCTYPE html>"); 
      out.println("<html>"); 
      out.println("<head>"); 
      out.println("<title>Servlet ConverterServlet</title>"); 
      out.println("</head>"); 
      out.println("<body>"); 

      out.println("what is the amount?"); 
      out.println("<h1>Servlet ConverterServlet at " + request.getContextPath() + "</h1>"); 

      String stringAmount = "999"; 
      out.println("amount is " + stringAmount); 
      out.println("<p>"); 
      BigDecimal dollars = new BigDecimal(stringAmount); 
      out.println("dollars:\t" + dollars + "\t" + dollars.getClass()); 
      out.println("<p>"); 

      BigDecimal yen = converter.dollarToYen(dollars); 
      BigDecimal euros = converter.yenToEuro(yen); 

      out.println("never executed.."); 
      out.println("yen"); 
      out.println(yen); 
      out.println("<p>"); 
      out.println("euros"); 
      out.println(euros); 
      out.println("<p>"); 

      out.println("</body>"); 
      out.println("</html>"); 

     } 
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> 
    /** 
    * Handles the HTTP <code>GET</code> method. 
    * 
    * @param request servlet request 
    * @param response servlet response 
    * @throws ServletException if a servlet-specific error occurs 
    * @throws IOException if an I/O error occurs 
    */ 
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     processRequest(request, response); 
    } 

    /** 
    * Handles the HTTP <code>POST</code> method. 
    * 
    * @param request servlet request 
    * @param response servlet response 
    * @throws ServletException if a servlet-specific error occurs 
    * @throws IOException if an I/O error occurs 
    */ 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     processRequest(request, response); 
    } 

    /** 
    * Returns a short description of the servlet. 
    * 
    * @return a String containing servlet description 
    */ 
    @Override 
    public String getServletInfo() { 
     return "Short description"; 
    }// </editor-fold> 

} 

和EJB:

的應用程序的
package net.bounceme.dur.ejb; 

import java.math.BigDecimal; 
import javax.naming.InitialContext; 
import javax.naming.NamingException; 
import java.util.Properties; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.ejb.Stateless; 

@Stateless 
public class ConverterBean { 

    private static final Logger log = Logger.getLogger(ConverterBean.class.getName()); 
    private static final Level LEVEL = Level.INFO; 
    private static final BigDecimal YEN_RATE = new BigDecimal("83.0602"); 
    private static final BigDecimal EURO_RATE = new BigDecimal("0.0093016"); 

    public BigDecimal dollarToYen(BigDecimal dollars) { 
     return YEN_RATE; 
    } 
    public BigDecimal yenToEuro(BigDecimal yen) { 
     return EURO_RATE; 
    } 

    public BigDecimal realdollarToYen(BigDecimal dollars) { 
     log.info("dollarToYen.." + dollars); 
     BigDecimal result = dollars.multiply(YEN_RATE); 
     return result.setScale(2, BigDecimal.ROUND_UP); 
    } 

    public BigDecimal realyenToEuro(BigDecimal yen) { 
     log.info("yenToEuro.." + yen); 
     BigDecimal result = yen.multiply(EURO_RATE); 
     return result.setScale(2, BigDecimal.ROUND_UP); 
    } 

    private void lookup() throws NamingException { 
     System.out.println("fuck"); 
     PropertiesReader pr = new PropertiesReader(); 
     Properties webService = pr.getProps("WebService"); 
     log.info(pr.toString()); 
     log.info(new InitialContext().getEnvironment().toString()); 
    } 

} 

樹視圖:

ConverterApplication/ 
├── build.xml 
├── ConverterApplication-ejb 
│   ├── build.xml 
│   ├── nbproject 
│   │   ├── ant-deploy.xml 
│   │   ├── build-impl.xml 
│   │   ├── genfiles.properties 
│   │   ├── private 
│   │   │   ├── private.properties 
│   │   │   └── private.xml 
│   │   ├── project.properties 
│   │   └── project.xml 
│   └── src 
│    ├── conf 
│    │   └── MANIFEST.MF 
│    └── java 
│     ├── net 
│     │   └── bounceme 
│     │    └── dur 
│     │     └── ejb 
│     │      ├── Client.java 
│     │      ├── ConverterBean.java 
│     │      └── PropertiesReader.java 
│     └── resources 
│      ├── JNDI.properties 
│      └── WebService.properties 
├── ConverterApplication-war 
│   ├── build.xml 
│   ├── nbproject 
│   │   ├── ant-deploy.xml 
│   │   ├── build-impl.xml 
│   │   ├── genfiles.properties 
│   │   ├── private 
│   │   │   ├── private.properties 
│   │   │   └── private.xml 
│   │   ├── project.properties 
│   │   └── project.xml 
│   ├── src 
│   │   ├── conf 
│   │   │   └── MANIFEST.MF 
│   │   └── java 
│   │    └── net 
│   │     └── bounceme 
│   │      └── dur 
│   │       └── ejb 
│   │        ├── ConverterServlet.java 
│   │        └── PropertiesReader.java 
│   ├── test 
│   └── web 
│    ├── index.html 
│    └── WEB-INF 
│     └── web.xml 
├── nbproject 
│   ├── ant-deploy.xml 
│   ├── build-impl.xml 
│   ├── genfiles.properties 
│   ├── private 
│   │   └── private.properties 
│   ├── project.properties 
│   └── project.xml 
└── src 
    └── conf 
     └── MANIFEST.MF 

28 directories, 35 files 

從:

https://docs.oracle.com/javaee/7/tutorial/ejb-gettingstarted001.htm

回答

1

添加在您的ConverterApplication戰和ConverterApplication的EJB模塊(在WEB-INF和META-INF文件夾)的類路徑空的beans.xml文件。他們需要發現注入的組件。

+0

這個工程。但是......它導致了這個Netbeans的「錯誤」:http://stackoverflow.com/q/12168353/262852,我認爲beans.xml過時了......這需要進一步的研究。我接受這個答案是沒有問題的,但是我們將不勝感激。 – Thufir

+0

@Thufir請顯示您的應用程序的更新樹視圖。 – Rinat

+0

更新的應用程序在這裏:http://stackoverflow.com/q/43488182/262852但它只是一個帶EJB本地接口的WAR而不是EAR。 – Thufir

0

溶液:

package net.bounceme.dur.ejb; 

import java.io.IOException; 
import java.io.PrintWriter; 
import java.math.BigDecimal; 
import javax.ejb.EJB; 
import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

@WebServlet(urlPatterns = "/") 
public class ConverterServlet extends HttpServlet { 

    @EJB 
    ConverterBean converter; 

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 
     converter = new ConverterBean(); 
     try (PrintWriter out = response.getWriter()) { 
      /* TODO output your page here. You may use following sample code. */ 
      out.println("<!DOCTYPE html>"); 
      out.println("<html>"); 
      out.println("<head>"); 
      out.println("<title>Servlet ConverterServlet</title>"); 
      out.println("</head>"); 
      out.println("<body>"); 

      out.println("what is the amount?"); 
      out.println("<h1>Servlet ConverterServlet at " + request.getContextPath() + "</h1>"); 

      String stringAmount = "999"; 
      out.println("amount is " + stringAmount); 
      out.println("<p>"); 
      BigDecimal dollars = new BigDecimal(stringAmount); 
      out.println("dollars:\t" + dollars + "\t" + dollars.getClass()); 
      out.println("<p>"); 

      BigDecimal yen = converter.dollarToYen(dollars); 
      BigDecimal euros = converter.yenToEuro(yen); 

      out.println("never executed.."); 
      out.println("yen"); 
      out.println(yen); 
      out.println("<p>"); 
      out.println("euros"); 
      out.println(euros); 
      out.println("<p>"); 

      out.println("</body>"); 
      out.println("</html>"); 

     } 
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> 
    /** 
    * Handles the HTTP <code>GET</code> method. 
    * 
    * @param request servlet request 
    * @param response servlet response 
    * @throws ServletException if a servlet-specific error occurs 
    * @throws IOException if an I/O error occurs 
    */ 
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     processRequest(request, response); 
    } 

    /** 
    * Handles the HTTP <code>POST</code> method. 
    * 
    * @param request servlet request 
    * @param response servlet response 
    * @throws ServletException if a servlet-specific error occurs 
    * @throws IOException if an I/O error occurs 
    */ 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     processRequest(request, response); 
    } 

    /** 
    * Returns a short description of the servlet. 
    * 
    * @return a String containing servlet description 
    */ 
    @Override 
    public String getServletInfo() { 
     return "Short description"; 
    }// </editor-fold> 

} 
然而

,實例化所述豆不應要求。正確還是錯誤?

看到:

NullPointerException in ejb injection

+4

這不是正確的答案。您正在獲得NPE,因爲您似乎在部署單獨的EJB jar和WAR模塊。 WAR文件類將無法查看EJB類。在過去,你會將它們打包在一個EAR文件中。但是對於Java EE 6和更新版本,您可以將所有類放在WAR文件中 - 或者將EJB jar文件包含在您的WEB-INF/lib目錄 –

+0

中,我並不完全遵循。是的,我的意圖是從WAR中分離出EJB。我只把它們堵在一起,這樣就可以更容易地將它們部署爲EAR。如果你想詳細說明,將不勝感激。 – Thufir

+0

Java EE規定模塊和部署之間的類可見性規則。通常,單獨的部署不能看到彼此的類。 –