0

I'm trying to write a simple login form with jsf and CDI. the problem is when I inject my SessionScoped bean it doesn't work as I expect. This is my bean

@Named
@SessionScoped
public class LoginInfo implements Serializable {
    private String uname;
    private String pass;
    private String pagename;
    private int count;

    public LoginInfo() {
    }

    public void increment() {
        count++;
    }
}

And this is my controller :

@Named
@RequestScoped
public class LoginPageMg {
    @Inject
    LoginInfo lo;

    public LoginPageMg() {
    }


    public void login() {
        lo.increment();
        lo.setPagename("aaa");
        int x = 8;
    }
}

And a simple Jsf form which calls login function and shows counter field of LoginInfo class.

<h:form prependId="false" id="mainform" styleClass="login-box">
                        <p:inputText value="#{loginPageMg.uname}"/>
                        <p:password value="#{loginPageMg.pass}"/>

                        <h:outputLabel id="counter" value="#{loginInfo.count}"></h:outputLabel>

                        <p:commandButton update="counter"
                                         action="#{loginPageMg.login}"
                                         value="login"></p:commandButton>
</h:form>

By clicking login button and debugging variables I can see "lo" is something like this :

lo = {LoginInfo$Proxy$_$$_WeldClientProxy@16688}"com.mg.LoginInfo@703ec5d5"

On line int x=8 I can see "lo" variables didn't changed at all but in my jsf page I can see the counter increases every time I press login button and bean holds the value after refreshing the page.

  1. What is WeldClientProxy?
  2. Why there are two different instance of a SessionScoped bean? Is that normal or I'm doing something wrong?
  3. How can I inject the same instance that jsf does?

I'm using Wildfly 15 Jsf 2.3.4 CDI 1.1

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
armin momeni
  • 181
  • 2
  • 10

1 Answers1

2

I'm using Wildfly 15 Jsf 2.3.4 CDI 1.1

WildFly 15 means EE 8 compatilibity, hence it comes with CDI 2.0.

Now to answer as much as I can from your questions:

What is WeldClientProxy?

Weld is a CDI reference implementation used by majority of EE servers out there, including WildFly. WeldClientProxy is an internal construct it uses for injection of normal scoped beans (pretty much all except @Dependent). It is not an actual instance of the bean, you can think of it as an "wrapper" that knows how to retrieve actual contextual instance and delegates calls to it. This way you can reuse the proxy instance while still pointing to the correct instance under the hood (hence the reference doesn't need to change).

Why there are two different instance of a SessionScoped bean? Is that normal or I'm doing something wrong?

There is only one, the client proxy isn't an actual instance. You basically verified that by seeing the count increase every time and keeping state between requests.

How can I inject the same instance that jsf does?

JSF doesn't actually inject anything, instead it uses expression language to find the bean based on its name. CDI allows you to define this name via @Named. JSF then gets to use the very same bean you are injecting, again via a proxy.

Siliarus
  • 6,393
  • 1
  • 14
  • 30
  • I changed CDI version from 1.1 to 2.0 but nothing changed. What is the point of Weld if i just can set it and not reading it's state? I managed to read the state with this article. http://docs.jboss.org/weld/reference/latest/en-US/html/example.html . – armin momeni Mar 14 '19 at 22:51
  • With CDI 2.0 I was merely pointing out that with that version of WFLY you are running 2.0 whether you like it or not (WFLY itself provides the dependency, not your project settings). Newer versions are backward compatible, so you shouldn't see much of a difference anyway. As for your other question, I am afraid I don't understand? – Siliarus Mar 15 '19 at 07:07
  • I got the logic so far thanks for that. the only question left is that why changes to bean doesnt appear on weld proxy ? The way the link i provided suggests is working. is it the best way possible or is there a better idea for this issue – armin momeni Mar 15 '19 at 14:43
  • The important part is that the setup works - new requests change the state of the bean and your application works. The fact that there is some proxy in between and that it behaves this or that way should be considered Weld's internal matter and shouldn't affect you. What happens there is that proxy is a new object that has the same type as your bean and has reference to the actual bean and forwards all method calls to it. Proxy objects stays the same, just the reference changes. That's, I suppose, what you mean by not seeing the changes to bean on proxy? – Siliarus Mar 18 '19 at 07:24
  • As i mentioned in my question in my login function, lo.count doesn't change and remains zero(I can see that on debugging). But I know count is changing And based on your answer there is only one instance – armin momeni Mar 19 '19 at 13:42