Cannot invoke method because inject is null

I’m creating web application and i’m using java ee 7, deploying it using maven tomcat plugin creating war. I have servlets, ejb, some logic, jpa integration and etc. I use command pattern to process requests. My main servlet fetches parameters and redirects user to the next page according on command from hidden input as a parameter.

I have sign in form and classes that realize login logic. These classes are next

EDIT (I edited my code adding injection of beans. Also i created according qualifiers for every command)

My code

SigninCommand.java

@SigninCommandQualifier
public class SigninCommand implements Command {

    @Inject
    private UserEJB userEJB;

    public String execute(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        User signinUser = new User(email, password);
        User foundUser = userEJB.findUser(signinUser);
        if (foundUser != null) {
            request.setAttribute("passedAuth", true);
            return PagesManager.getProperty("page.nameGeneration");
        } else {
            request.setAttribute("passedAuth", false);
            return PagesManager.getProperty("page.signin");
        }
    }
}

UserEJB.java

@Stateless
public class UserEJB implements UserEJBRemote{
    @Inject
    private EntityManager em;
    public List<User> findUsers() {
        TypedQuery<User> query = em.createNamedQuery(FIND_ALL, User.class);
        return query.getResultList();
    }

    public User findUser(@NotNull User user) {
        return em.find(User.class, user);
    }

    public
    @NotNull
    User createUser(@NotNull User user) {
        em.persist(user);
        return user;
    }

    public
    @NotNull
    User updateUser(@NotNull User user) {
        return em.merge(user);
    }

    public void deleteUser(@NotNull User user) {
        em.remove(em.merge(user));
    }
}

beans.xml

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

ProjectServlet.java

public class ProjectServlet extends HttpServlet {

    @Inject
    @EmptyCommandQualifier
    private Command command;

    @Inject
    private ActionFactory actionFactory;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String action = request.getParameter("command");
        try {
            command = actionFactory.defineCommand(action);
        } catch (IllegalArgumentException e) {
            request.setAttribute("msg", action + " " + MessageManager.getProperty("message.wrongaction"));
        }
        String page;
        try {
            page = command.execute(request, response);
        } catch (IOException e) {
            page = PagesManager.getProperty("page.error");
        }
        if (page != null) {
            if (page.equals("not redirecting")) {
                return;
            }
            RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(page);
            dispatcher.forward(request, response);
        } else {
            page = PagesManager.getProperty("page.index");
            request.getSession().setAttribute("nullPage",
                    MessageManager.getProperty("message.nullpage"));
            response.sendRedirect(request.getContextPath() + page);
        }
    }
}

Command.java

public interface Command {
    String execute(HttpServletRequest request, HttpServletResponse response) throws IOException;
}

CommandEnum.java

public enum CommandEnum {

    EMPTY_COMMAND {
        {
            this.command = emptyCommand;
        }
    },
    NAME_GENERATION {
        {
            this.command = nameGenerationCommand;
        }
    },
    NAME_GENERATION_SETTINGS {
        {
            this.command = nameGenerationSettingsCommand;
        }
    },
    SIGNIN {
        {
            this.command = signinCommand;
        }
    };

    Command command;

    @Inject
    EmptyCommand emptyCommand;
    @Inject
    NameGenerationCommand nameGenerationCommand;
    @Inject
    NameGenerationSettingsCommand nameGenerationSettingsCommand;
    @Inject
    SigninCommand signinCommand;

    public Command getCommand() {
        return command;
    }
}

ActionFactory.java

public class ActionFactory {

    @Inject
    @EmptyCommandQualifier
    private Command command;

    @Inject
    private CommandEnum commandEnum;

    public Command defineCommand(String action) throws IllegalArgumentException {
        if (action == null || action.isEmpty()) {
            return command;
        }
        commandEnum = CommandEnum.valueOf(action.toUpperCase());
        command = commandEnum.getCommand();
        return command;
    }

    @Produces
    public static CommandEnum getEmptyCommandEnum()
    {
        return CommandEnum.EMPTY_COMMAND;
    }
}

The problem

When i click sign in button on login page i catch next exception:

java.lang.NullPointerException: Cannot invoke "factory.ActionFactory.defineCommand(String)" because "this.actionFacto
ry" is null
        at servlet.ProjectServlet.processRequest(ProjectServlet.java:39)
        at servlet.ProjectServlet.doPost(ProjectServlet.java:33)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at java.base/java.lang.Thread.run(Thread.java:832)
        at org.apache.coyote.http11.AbstractHttp11Proces
sor.process(AbstractHttp11Processor.java:1041)
        at org.apache.coyote.AbstractProtocol$AbstractCo
nnectionHandler.process(AbstractProtocol.java:603)
        at org.apache.tomcat.util.net.JIoEndpoint$Socket
Processor.run(JIoEndpoint.java:310)
        at java.base/java.util.concurrent.ThreadPoolExec
utor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExec
utor$Worker.run(ThreadPoolExecutor.java:630)
        at java.base/java.lang.Thread.run(Thread.java:83
2)

actionFactory is null and i don’t know why.

What i’ve tried

  1. Adding @Stateless annotation to SigninCommand
  2. Adding bean.xml file to WEB-INF folder (before it was placed at META-INF)
  3. Clear IDEA cache
  4. Attach @Named annotation to UserEJB class

But i still get NPE.

Help, please.

Answer

The Problem was, besides the usage of new for CDI-beans, that tomcat was used as container without any additions like Weld-Standalone. Therefore neither Ejb-Annotations like @Ejb, @Standalone,… nor CDI-Annotations like @Inject had any effect during deployment of the war-file. The reasonable solution for that is to switch from a pure servlet-container to a microprofile-container like wildfly, kumuluzee …

Leave a Reply

Your email address will not be published. Required fields are marked *