Tobias
Tobias

Reputation: 1

@EJB makes program crash

Working on a basic web application with JavaEE. I've created a JavaBean, a Bean Interface, a Servlet, an Entity and a Jsp page (attached bellow). When I request the servlet URL it get error message Error instantiating servlet class and the root cause is:

javax.naming.NameNotFoundException: Name [com.packageName.UserServlet/userDao] is not bound in this Context. Unable to find [com.packageName.UserServlet]. 

The weird thing (in my opinion) is that when I remove the @EJB annotation in the UserServlet class, it works. I don't understand why..

If I just remove the @EJB it's a problem when executing userDao.addUser(user) (NullPointerException) which I think is because I removed the the @EJB?

I'm a beginner to JavaEE so my terminology might be a bit wrong but I hope you understand my problem.

Class: UserServlet

@WebServlet(name = "UserServlet", urlPatterns = {"/UserServlet"})
public class UserServlet extends HttpServlet {

@EJB("UserDaoBean") <---- This annotation makes it crash
private UserDaoLocal userDao;

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    int userId = 2;
    User user = new User(userId, "userName", "password");
    userDao.addUser(user);
    request.getRequestDispatcher("userinfo.jsp").forward(request, response);
}

Class: User

@Entity
@Table
@NamedQueries(@NamedQuery(name = "User.getAll", query = "select e from User e"))
public class User implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private int userid;
@Column
private String name;
@Column
private String password;

public User() {
}

public User(int userid, String name, String password) {
    this.userid = userid;
    this.name = name;
    this.password = password;
}

public int getUserid() {
    return userid;
}

public void setUserid(int userid) {
    this.userid = userid;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}
}

Class: UserDaoLocal

public interface UserDaoLocal {

void addUser(User user);

}

Class: UserDaoBean

@Local
@Stateless(name = "UserDaoBean")
public class UserDaoBean implements UserDaoLocal {

@PersistenceContext
private EntityManager entityManager;

public UserDaoBean() {
}

@Override
public void addUser(User user) {
    entityManager.persist(user);
}
}

Upvotes: 0

Views: 149

Answers (2)

Priyamal
Priyamal

Reputation: 2989

why are you annotating the UserDaoBean with @localbean annotation when you already have a interface view, @localbean should be used if there is no- interface view. annotate the interface with @local annotation since it represents the bean's local view. and it seems that you have given a name to the bean

@Stateless(name = "UserDaoBean")
public class UserDaoBean implements UserDaoLocal {}

since you have overidden the default class name you cant just use @EJB specify the bean name with @EJB(beanName="UserDaoBean") private UserDaoLocal userDao;

or just remove the name attribute in the stateless annotation

@Stateless
public class UserDaoBean implements UserDaoLocal {}

And make the ejb call like this

    @EJB
    UserDaoLocal userbean

Make sure to clean and build before running it.

Upvotes: 1

davidxxx
davidxxx

Reputation: 131476

@WebServlet seems not work very naturally with EJB injection. In your exception, we can see that the container used a weird JNDI name to locate your EJB instance : com.packageName.UserServlet/userDao

Even if it is boiler plate code, you could try to do as in the past to bypass this problem : declare your EJB in your web.xml such as :

 <ejb-local-ref>
    <ejb-ref-name>UserDaoBean</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local>yourPackage.UserDaoBean</local>
  </ejb-local-ref>

Upvotes: 0

Related Questions