learner420
learner420

Reputation: 182

jsf: Calling a method in managedbean giving exception

When I am trying to access the login method of my managed bean by following code in my xhtml:

<p:commandButton value="Login" update="growl"
                                actionListener="#{loginView.login}"/>

my LoginView class looks like this:

@Component
@ManagedBean(name="loginView",eager=true)
@SessionScoped
public class LoginView {
@Autowired
LoginService loginServiceImpl;
Student student=loginServiceImpl.login(username, password);

 public void login(ActionEvent event) {
        RequestContext context = RequestContext.getCurrentInstance();
        FacesMessage message = null;
        boolean loggedIn = false;
if(username != null && student!=null && password != null ) {
loggedIn=True;

try {
                FacesContext.getCurrentInstance()
                .getExternalContext()
                .redirect(location);
            } catch (IOException e) {

                e.printStackTrace();
            }
}
}

when I am calling pressing the button its giving me the following error:

javax.el.ELException: /login1.xhtml @105,62 actionListener="#{loginView.login}": java.lang.NullPointerException
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:111)
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:147)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:818)
at javax.faces.component.UICommand.broadcast(UICommand.java:300)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
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:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
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.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.primefaces.showcase.view.menu.LoginView.login(LoginView.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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)
... 26 more

Strangely, When I am commenting the line

Student student=loginServiceImpl.login(username, password);

The code is working fine. I want my bean to be both, Spring based as I want to autowire loginServiceImpl and jsf based as I want to call my method. If It's not possible, what approach should I chose.

Upvotes: 0

Views: 1007

Answers (2)

learner420
learner420

Reputation: 182

Thanks wittakarn to spend time to answer the question, but it answers the question partially. I researched on the topic and found a really good article on the same here

We can't inject spring bean by using @Autowired in a JSF managed bean as JSF beans are serializable which is not the case with Spring bean. Approach taken by @wittakarn is nice, except there is one problem. In the setter of the loginService, I have to create a new loginService object and give it's reference to "this" class, where all the concept of loose coupling breaks!!!

rather, there is one good approach. Spring wants it's bean to be non-seriazable. So first we have to make the loginService, a non serialized property by making it transient, and then in the init method call the externalContext and give the capabilities of autowiring to "this" class. The code would look like this:

@Autowired
    transient LoginService loginServiceImpl;
    @PostConstruct
    private void init() {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        ServletContext servletContext = (ServletContext) externalContext.getContext();
        WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext).
        getAutowireCapableBeanFactory().
        autowireBean(this);
    }

and guess what!! it's working :)

Upvotes: 1

wittakarn
wittakarn

Reputation: 3162

You cannot inject a Spring bean by using @Autowired inside JSF managed bean.

You should change to

@ManagedProperty(value="#{something}")
private LoginService loginServiceImpl; // getter and setter.

See also: Null pointer when autowiring the bean into JSF Managed bean

Upvotes: 2

Related Questions