javapenguin
javapenguin

Reputation: 1036

Liberty profile not injecting ejb in servlet

I googled without luck trying to understand why Liberty Profile 8.5.5.6 does not inject EJB into a servlet

I put everything into a war. The war deployed fine, but when I call the servlet I get the following error:

Exception thrown by application class 'org.javaee7.servlet.simple.UserServlet.doGet:23'
java.lang.NullPointerException:
at org.javaee7.servlet.simple.UserServlet.doGet(UserServlet.java:23)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1285)
at [internal classes]

On this link I saw a comment that I should use @ManagedBean

When I try this, the null pointer exception goes away but now I get this error:

Error 404: javax.servlet.UnavailableException: SRVE0319E: For the [UserServlet] servlet, org.javaee7.servlet.simple.UserServlet servlet class was found, but a resource injection failure has occurred. CWNEN0030E: The server was unable to obtain an object instance for the java:comp/env/org.javaee7.servlet.simple.UserServlet/service reference. The exception message was: The EJB reference in the lps.war module of the lps application could not be resolved; nested exception is: com.ibm.ejs.container.EJBNotFoundException: EJB with interface org.javaee7.service.UserService not present in application lps. 

Here is my code:

@Stateless
public class UserServiceImpl implements UserService {
    public User getUser(Long id) {
        return new User(id, "Gary");
    }
}

@Remote
public interface UserService {
    public User getUser(Long id);
}

@ManagedBean
public class UserServlet extends HttpServlet {
    @EJB(mappedName = "UserServiceImpl")
    UserService service;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User user = service.getUser(1L);
        response.getWriter().print(user == null ? "no user" : user.toString());
    }
}

Upvotes: 3

Views: 6105

Answers (1)

Gas
Gas

Reputation: 18030

First - for sure you shouldn't use @ManagedBean. Servlet is not a managed bean. You dont need that for injection to work. You should have either @WebServlet in your servlet or configure it via web.xml.
Second - you should remove mappedName as Liberty is not using that.

Please add server.xml to your question as you may be lacking some features.
You should have either ejbRemote-3.2 or javaee-7.0 feature there among others.

For remote interfaces you have to use the following binding:

@EJB(lookup="java:global/AppName/ModuleName/UserServiceImpl!org.javaee7.service.UserService")
private UserService service;

You can also use other bindings like below depending on your config:

java:global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface    
java:app/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface    
java:module/ExampleBean!com.ibm.example.ExampleRemoteInterface

When your bean is binding you should see the following message in the log:

[INFO    ] CNTR0167I: The server is binding the com.ibm.example.ExampleRemoteInterface interface of the ExampleRemote enterprise bean in the Example.war module of the Example application.  
The binding location is: java:global/Example/ExampleRemote!com.ibm.example.ExampleRemoteInterface

UPDATE
In case of same app just @EJB without any lookup works for me also.

See also for more details:

Upvotes: 2

Related Questions