2017-04-17 76 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规定模块和部署之间的类可见性规则。通常,单独的部署不能看到彼此的类。 –