4

I try write my first JSF2.0 project (with using EJB3.1). I don't understand why my @ManagedBean annotation not work.

I always get an error, when I run application on Glassfish v3

exception

javax.servlet.ServletException: /login.xhtml @34,133 value="#{loginBean.login}": Target Unreachable, identifier 'loginBean' resolved to null

root cause

javax.el.PropertyNotFoundException: /login.xhtml @34,133 value="#{loginBean.login}": Target Unreachable, identifier 'loginBean' resolved to null

If I define a managed bean in faces-config.xml - it will work. But I want to use annotation.

May be I use wrong libraries in my poms?

Example of managedbean (it will be a transfer object):

package edu.tsystems.vmmail.web.core.domain;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import java.io.Serializable;

@ManagedBean
@ViewScoped
public class LoginBean implements Serializable {
    private String login;
    private String password;

    public LoginBean() {}

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

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

login.xhtml (where i can try to use it):

<!DOCTYPE html
        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html   xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:p="http://primefaces.org/ui">
    <f:loadBundle var="common" basename="edu.tsystems.vmmail.web.ui.MessageResources" />
    <h:head>
        <title>Welcome to VMMail Web Interface</title>
        <link type="text/css" href="#{request.contextPath}/css/style.css" rel="stylesheet" />
    </h:head>
    <h:body>
        <f:view>
            <h:form id="loginForm" method="post">
                <p:panelGrid id="mainLogin" styleClass="noInnerBorderTable">
                    <f:facet name="header">
                        <p:row>
                            <p:column colspan="4">
                                <h:outputText value="#{common['login.welcome']}" /><br/>
                                <h:message for="loginBean" id="login1Error" />
                            </p:column>
                        </p:row>
                    </f:facet>
                    <p:row>
                        <p:column rowspan="2">
                            <div class="logoCell"></div>
                        </p:column>
                        <p:column>
                            <h:outputText value="#{common['field.login']}" for="loginBean" />
                        </p:column>
                        <p:column>
                            <p:inputText id="loginBean" required="true" value="#{loginBean.login}" requiredMessage="#{common['field.login.required']}" />
                        </p:column>
                        <p:column rowspan="2">
                            <div class="submitButtonCell">
                                <p:commandLink styleClass="loginAnchor" title="#{common['field.loginButton']}"
                                        action="#{userController.loggingIn(login)}" ajax="false" />
                            </div>
                        </p:column>
                    </p:row>
                    <p:row>
                        <p:column>
                            <h:outputText for="password" value="#{common['field.password']}" />
                        </p:column>
                        <p:column>
                            <p:password id="password" required="true" value="#{loginBean.password}" requiredMessage="#{common['field.password.required']}" />
                        </p:column>
                    </p:row>

                    <f:facet name="footer">
                        <p:row>
                            <p:column colspan="4">
                                <h:outputText value="#{common['login.notHave']}" />
                                <a href="#{request.contextPath}/registration.xhtml">
                                    <h:outputText value="#{common['login.registerNow']}" />
                                </a>
                            </p:column>
                        </p:row>
                    </f:facet>
                </p:panelGrid>
            </h:form>
        </f:view>
    </h:body>
</html>

UserController class:

package edu.tsystems.vmmail.web.core.controllers;

import edu.tsystems.vmmail.web.core.dao.UserDAO;
import edu.tsystems.vmmail.web.core.domain.LoginBean;
import edu.tsystems.vmmail.web.core.model.UserEntity;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

@Stateless
@ViewScoped
public class UserController {
    @EJB
    private UserDAO userDAO;
    private UserEntity user;

    public boolean isLoggedIn() {
        return user != null;
    }

    public String loggingIn(LoginBean loginBean) {
        FacesContext context = FacesContext.getCurrentInstance();

        if(userDAO == null) {
            context.addMessage("loginForm:login1Error", new FacesMessage("DAO IS NULL!"));
//          return "/loginBean.xhtml?faces-redirect=true&error=1";
        }

        user = userDAO.getUserByLoginAndPassword(loginBean.getLogin(), loginBean.getPassword());
        if (user != null) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);

            session.setAttribute("user", user.getId());
            return "/mail/mail.xhtml?faces-redirect=true";
        } else {
            return "/loginBean.xhtml?faces-redirect=true";
        }
    }

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "/login.xhmtl?faces-redirect=true";
    }
}

I really not understand why it not works :( What do I do wrong?

UPD: Stack trace: http://pastebin.com/istJmMHr

Source code may be downloaded from my google drive: https://docs.google.com/file/d/0B4Am7SXJwmtKNVc0LVhWVlEyMVk/view

beowulf13th
  • 447
  • 1
  • 6
  • 16
  • Can you define "not working" in more programmer way, not like user? – partlov Mar 12 '13 at 15:21
  • oh, sry, I forgot describe an error :( updated post. – beowulf13th Mar 12 '13 at 15:38
  • @beowulf13th can you just delete the controller and create it again? Do you get the same error? i also doubt that container issue can you try tomcat ? – berkay Mar 12 '13 at 16:13
  • @berkay I can't deploy it into tomcat because I make a EAR package. I created UserTwoController with annotation @ javax.ejb.Stateless and @ javax.faces.bean.ViewScoped and LoginBeanTwo with annotation @ javax.faces.bean.ManagedBean and @ javax.faces.bean.ViewScoped. But it does not have any effect. – beowulf13th Mar 12 '13 at 17:36
  • @beowulf13th post your full stacktrace here. There's likely an underlying cause why loginBean wasn't instantiated. It looks like you're trying to combine an EJB and a managed bean in one. Don't do it. – kolossus Mar 12 '13 at 19:30
  • @kolossus http://pastebin.com/7Ncw8GRe full trace from deploy to error. – beowulf13th Mar 13 '13 at 04:02

2 Answers2

0

I think you can better start with a really small example to get a grasp of things. There are many things not quite right in your code.

To start, an @Stateless bean can't be view scoped. Think about this for a moment. What would it actually mean to have a stateless view scoped bean? Why did you think you needed one in the first place?

A view should have one backing bean and this one is often view scoped. Any DTOs that you might need for that view should not be view scoped, but should just be instance variables of the main backing bean. That way they'll be automatically dependent on that scope.

In your case, make loginBean an instance variable just like the user variable.

Mike Braun
  • 3,729
  • 17
  • 15
  • Completely wrong statement. @Stateless can be view scoped. Wake up. – Makky May 09 '13 at 12:59
  • @Makky I'm really curious now. Why do you think a Stateless bean can be view scoped, and what does a "stateless view scoped bean" semantically mean? If the user navigates away from the view, how does the container destroy the stateless bean? And how does the container ensure that all requests to this view scoped stateless bean go to the same bean instance? Please educate me! Thanks in advance :) – Mike Braun May 15 '13 at 09:05
  • I meant to say Stateless EJB can be used in Viewscoped Managed Bean. Why not – Makky May 15 '13 at 13:31
  • @Makky Of course a view scoped bean can *use* a stateless bean. That's in fact one of the most common use cases. Why shouldn't this be possible? Who said this wasn't possible? – Mike Braun May 15 '13 at 17:15
0

It happend because my @ManagedBean was placed in EJB package, not in WAR package.

When I moved all @ManagedBeans into my WAR module all earned!

beowulf13th
  • 447
  • 1
  • 6
  • 16