2

I'm designing a JSF application with managed beans. For the moment, I've only been trying to create a simple login page (username and password are hard-coded for the moment) :

<h:form class="form-signin">
    <h2 class="form-signin-heading">Please sign in</h2><hr />
    <input name="username" type="text" class="input-block-level" placeholder="Username" />
    <input name="password" type="password" class="input-block-level" placeholder="Password" />
    <h:commandButton action="#{userController.login}" class="btn btn-block btn-primary" type="submit" value="Sign in" />
</h:form>

Here is the controller (UserController.java) :

@ManagedBean(name="userController")
@ApplicationScoped
public class UserController {

    @EJB
    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public UserController() {
    }

    public void login() throws IOException {
        Boolean login = userService.login("admin", "p4ssw0rd");
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        if (login == true) { 
            externalContext.redirect("dashboard.xhtml");
        } else {
            externalContext.redirect("login.xhtml");
        }
    }
}

And this is the UserService.java file :

@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

    public static String md5(String input) {
        // Removed for clarity...
    }

    public Boolean login(String username, String password) {
        //String hash = md5(password);
        return Boolean.TRUE; // As you can see, nothing can fail for the moment
    }

}

When I submit the login form, a NullPointerException shows up :

javax.faces.el.EvaluationException: java.lang.NullPointerException
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    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:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    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:1008)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.NullPointerException
    at com.myname.myproject.managedbean.UserController.login(UserController.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    ... 24 more

In UserController.java, if I replace this line :

Boolean login = userService.login("admin", "p4ssw0rd");

By this one :

Boolean login = true; // Or false (I've tested twice)

Everything works OK, so it seems like Java fails to find the UserService...

Thanks for your help, I'm completely lost.

mimipc
  • 1,354
  • 2
  • 14
  • 28
  • Which one is the line 33 in your `UserController` class? Taken from your stacktrace: `java.lang.NullPointerException at com.myname.myproject.managedbean.UserController.login(UserController.java:33)`. – Luiggi Mendoza May 28 '13 at 15:26
  • By the way, are you running this on Tomcat or in a Java EE application server e.g. GlassFish 3, JBoss 7, TomEE... – Luiggi Mendoza May 28 '13 at 15:26
  • I'm running this on a Tomcat server and line 33 is `public void login() throws IOException {`. Do I need to reference my bean in faces-config.xml? – mimipc May 28 '13 at 15:46

3 Answers3

0

Did you check putting getters and setters in your managed bean called UserController?

If you did not, even if the code compiles correctly, dependency injection would not be held correctly.

talhaocakci
  • 141
  • 1
  • 9
0

I believe that the problem is the EJB. It should be annotated @LocalBean if it is no-interface bean or implement an interface otherwise. Try something like this:

@Stateless
public class UserService implements UserServiceLocal {

    @Override
    public boolean login () {
        //dummy implementation
        return true;
    }
}

where UserServiceLocal is:

@Local
public interface UserServiceLocal {

    public boolean login();
}

Usage:

@ManagedBean(name="userController")
@ApplicationScoped
public class UserController {

    @EJB
    private UserServiceLocal userService;

    public void login() {
       userService.login();
    }
}
  • Thanks for your answer. I'm a Java noob, so could you tell me why it should implement an interface (it seems very verbose) and what's the difference between an EJB and a local bean? – mimipc May 28 '13 at 13:32
0

Regarding your question about why it should implement an interface, please see EJB's - when to use Remote and/or local interfaces?. An EJB (enterprise java bean) can have an interface (which can be annotated with @Remote, meaning that the bean who implements it runs in a distributed environment, or annotated with @Local meaning the bean runs inside the same JVM. In contrast, a no-interface bean is a bean that does not implements any interface. Therefore, you should instruct JVM to treat it as a bean instead of a POJO (plain old java object); this can be accomplished by adding @LocalBean annotation on the class that it is supposed to be your bean /EJB.

Community
  • 1
  • 1