Servlet.service() for servlet jsp threw exception java.lang.NullPointerException while calling EJB bean

16,947

The @PersistenceContext won't be injected if you manually instantiate an EJB class as a simple java bean in JSP by <jsp:useBean> instead of getting a container managed instance by @EJB. I don't know how and where you learned to write JSPs that way, but it's undoubtely based on a heavily outdated book/tutorial. You need to make drastic changes in your current model-view-without-controller approach. You need to add a controller. Throw all those <jsp:xxx> tags away and create a Servlet which acts as a real controller.

E.g.

@WebServlet("/students")
public class StudentsServlet extends HttpServlet {

    @EJB
    private UsersFacade usersFacade;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("users", usersFacade.findAllStudents());
        request.getRequestDispatcher("/WEB-INF/students.jsp").forward(request, response);
    }

}

Note that I moved your JSP into /WEB-INF folder so that it's not possible to either purposefully or accidently invoke it without calling the servlet.

Now, change your JSP as follows:

<%@page pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h4>List of all students:</h4>
        <form action="${pageContext.request.contextPath}/edit" method="post">
            <c:forEach items="${users}" var="user" varStatus="loop">
                <p><c:out value="${user.name} ${user.surname}" /></p>
                <input type="submit" name="Edit_${loop.index}" value="Edit" />
                <input type="submit" name="Delete_${loop.index}" value ="Delete"/> 
            </c:forEach>
            <input type="submit" name="Add_new_student" value ="Add new student"/>
        </form>
    </body>
</html>

Open it by the servlet's URL http://localhost:8080/AppJPA/students so that its doGet() will to the right job and that the JSTL <c:forEach> will iterate over users accordingly.

I have by the way my doubts about the way how you named the buttons. Identifying the selected user would be very clumsy. But that's subject for a different question.

See also:

Share:
16,947
ferbolg
Author by

ferbolg

Student at National University "Kyiv-Mohyla academy", Kyiv, Ukraine. Currently I am trying myself out as Java/GWT developer.

Updated on June 04, 2022

Comments

  • ferbolg
    ferbolg almost 2 years

    While calling EJB bean on my simple jsp page I have such an error:

     WARNING: StandardWrapperValve[jsp]: PWC1406: Servlet.service() for servlet jsp threw 
     exception java.lang.NullPointerException
    at appjpa.ejb.UsersFacade.findAllStudents(UsersFacade.java:65)
    at org.apache.jsp.Students_jsp._jspService(Students_jsp.java from :75)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:403)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:662)
    

    Code for my jsp page is such:

    <%@page import="appjpa.entities.Users"%>
    <%@page import="java.util.ArrayList"%>
    <%@page import="socnet2.Student"%> <!-- class Student emulates real student -->
    <%@page contentType="text/html" pageEncoding="UTF-8"%>
     <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <jsp:useBean class="appjpa.ejb.UsersFacade" id="dao" scope="application"></jsp:useBean>
        <p><b>List of all students:</b></p>
        <form action="/AppJPA/Edit" method="POST">
           <jsp:scriptlet>
           int counter = 0;  if (dao != null){
           for (Users s : dao.findAllStudents()) {
            </jsp:scriptlet>
            <p> <jsp:expression> s.getName() + " " + s.getSurname()</jsp:expression></p>
            <input type="submit" name="Edit_<%=counter%>" value="Edit" />
            <input type="submit" name="Delete_<%=counter%>" value ="Delete"/> 
             <jsp:scriptlet>
                    counter++;
                }}
            </jsp:scriptlet>
            <input type="submit" name="Add_new_student" value ="Add new student"/>
        </form>
    </body>
    

    Autogenerated by NetBeans 7.0.1 wizard entity class for users looks like:

     @Entity
    @Table(name = "USERS")
    @NamedQueries({
    @NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
    @NamedQuery(name = "Users.findById", query = "SELECT u FROM Users u WHERE u.id = :id"),
    @NamedQuery(name = "Users.findByName", query = "SELECT u FROM Users u WHERE u.name =      :name"),
    @NamedQuery(name = "Users.findBySurname", query = "SELECT u FROM Users u WHERE u.surname = :surname"),
    @NamedQuery(name = "Users.findByLogin", query = "SELECT u FROM Users u WHERE u.login = :login"),
    @NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password"),
    @NamedQuery(name = "Users.findByRole", query = "SELECT u FROM Users u WHERE u.role = :role")})
    public class Users implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    // @NotNull
    @Column(name = "ID")
    private Integer id;
    @Size(max = 40)
    @Column(name = "NAME")
    private String name;
    @Size(max = 40)
    @Column(name = "SURNAME")
    private String surname;
    @Size(max = 40)
    @Column(name = "LOGIN")
    private String login;
    @Size(max = 40)
    @Column(name = "PASSWORD")
    private String password;
    @Size(max = 40)
    @Column(name = "ROLE")
    private String role;
    @ManyToMany(mappedBy = "usersList")
    private List<SubjectGroup> subjectGroupList;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idCreator")
    private List<SubjectGroup> subjectGroupList1;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idSender")
    private List<Messages> messagesList;
    
    public Users() {
    }
    
    public Users(Integer id) {
        this.id = id;
    }
    
    public Integer getId() {
        return id;
    }
    
    public void setId(Integer id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getSurname() {
        return surname;
    }
    
    public void setSurname(String surname) {
        this.surname = surname;
    }
    
    public String getLogin() {
        return login;
    }
    
    public void setLogin(String login) {
        this.login = login;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public String getRole() {
        return role;
    }
    
    public void setRole(String role) {
        this.role = role;
    }
    
    public List<SubjectGroup> getSubjectGroupList() {
        return subjectGroupList;
    }
    
    public void setSubjectGroupList(List<SubjectGroup> subjectGroupList) {
        this.subjectGroupList = subjectGroupList;
    }
    
    public List<SubjectGroup> getSubjectGroupList1() {
        return subjectGroupList1;
    }
    
    public void setSubjectGroupList1(List<SubjectGroup> subjectGroupList1) {
        this.subjectGroupList1 = subjectGroupList1;
    }
    
    public List<Messages> getMessagesList() {
        return messagesList;
    }
    
    public void setMessagesList(List<Messages> messagesList) {
        this.messagesList = messagesList;
    }
    
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }
    
    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Users)) {
            return false;
        }
        Users other = (Users) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }
    
    @Override
    public String toString() {
        return "appjpa.entities.Users[ id=" + id + " ]";
    }
    
    }
    

    And, finaly, class UsersFacade is such:

    @Stateless
    public class UsersFacade extends AbstractFacade<Users> implements UsersFacadeLocal {
    @PersistenceContext(unitName = "AppJPAPU")
    private EntityManager em;
    
    protected EntityManager getEntityManager() {
        return em;
    }
    
    public UsersFacade() {
        super(Users.class);
    }
    
    @Override
    public Users checkInBase(String login, String password) {
        Users u = (Users)(em.createNamedQuery("Users.findByLogin").setParameter("login",      login).getSingleResult());
    
        return u;
    }
    
    @Override
    public void removeUserFromSubjectGroup(Users user, SubjectGroup group) {
        Users u = em.find(Users.class, user.getId());
        SubjectGroup g = em.find(SubjectGroup.class, group.getId());
        if (u != null && g != null) {
            user.getSubjectGroupList().remove((SubjectGroup)group);
            group.getUsersList().remove(user);
            em.merge(user);
            em.merge(group);
        }
    }
    
    @Override
    public void addUserToSubjectGroup(Users user, SubjectGroup group) {
        Users u = em.find(Users.class, user.getId());
        SubjectGroup g = em.find(SubjectGroup.class, group.getId());
        if (u != null && g != null) {
            user.getSubjectGroupList().add((SubjectGroup)group);
            group.getUsersList().add(user);
            em.merge(user);
            em.merge(group);
        }
    }
    
    @Override
    public List<Users> findAllStudents() {
        String role = new String("student");
         List<Users> students = (List<Users>)(em.createNamedQuery("SELECT u FROM Users u WHERE u.role = :role").setParameter("role", role).getResultList());
         if (students == null){
             System.out.println("Students are null!!!");
         }
    
        return students;
    }
    
    @Override
    public boolean deleteStudent(Users user) {
        Users u = em.find(Users.class, user.getId());
        em.remove(user);
        return true;
    }
    
    @Override
    public boolean updateStudent(Users studentToEdit, String newName, String newSurname, String newLogin, String newPassword) {
        Users u = em.find(Users.class, studentToEdit.getId());
        u.setName(newName);
        u.setSurname(newSurname);
        u.setLogin(newLogin);
        u.setPassword(newPassword);
         em.merge(studentToEdit);
        return true;
    }
    
    @Override
    public void insertStudenttoDB(Users student, String newName, String newSurname, String newLogin, String newPassword) {
       em.persist(student);
       Users u = em.find(Users.class, student.getId());
        if (u != null) {
        student.setName(newName);
        student.setSurname(newSurname);
        student.setLogin(newLogin);
        student.setPassword(newPassword);  
        em.merge(student);
        }
    }     
    }
    

    I am quite new to EJB and maybe I am not using them right. I tried calling other methods from UsersFaced at another pages, but received the same error. Please, explain what I am doing wrong...

  • ferbolg
    ferbolg over 12 years
    Thanks for answer.I have a controler servlet in my application, my problem that I am not using it properly in some cases(. I added @EJB private UsersFacade usersFacade; inside servlet, but now I receive javax.servlet.ServletException: PWC1392: Error instantiating servlet class control.Controler, root cause: com.sun.enterprise.container.common.spi.util.InjectionExcept‌​ion: Exception attempting to inject Remote ejb-ref name=control.Controler/usersFacade and some other root cases.
  • BalusC
    BalusC over 12 years
    Then you've a problem in your EJB design/implementation which caused that the container was not able to create and manage it. The bottommost root cause of the stack trace contains the answer to this problem. If you really can't figure it out, ask a new question. This is offtopic from this question.