Auto-instantiate session-scoped bean from view-scoped bean - jsf-2

Every time I try to inject a session-scoped bean into my view-scoped beans, I get a NullPointerException when calling said bean. This problem is directly related to auto -instantiate a session bean?
Here is what I tried so far:
faces-config.xml
<managed-bean>
<managed-bean-name>sessionBean</managed-bean-name>
<managed-bean-class>com.example.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>viewBean</managed-bean-name>
<managed-bean-class>com.example.ViewBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
<managed-property>
<property-name>sessionBean</property-name>
<property-class>com.example.SessionBean</property-class>
<value>#{sessionMBean}</value>
</managed-property>
</managed-bean>
SessionBean.java:
package com.example;
public class SessionBean {
public SessionBean() {
System.out.println("Session is instantiated.");
}
public void sayHello() {
System.out.println("Hello from session");
}
}
ViewBean.java:
package com.example;
public class ViewBean {
private SessionBean sessionBean;
private String text = "Look at me!";
public ViewBean() {
System.out.println("View bean is instantiated.");
sessionBean.sayHello();
}
public SessionBean getSessionBean() {
return sessionBean;
}
public void setSessionBean(SessionBean sessionBean) {
this.sessionBean = sessionBean;
}
public String getText() {
return text;
}
}
and the relevant content of index.xhtml:
<f:view>
<h:outputText value="#{viewBean.text}"/>
</f:view>
And this is what I get:
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.example.ViewBean.
...
Caused by: java.lang.NullPointerException
at com.example.ViewBean.(ViewBean.java:12)
This runs (or rather doesn't run) on weblogic-10.3.6 with the shipped jsf-2-0.war deployed as a library.
What am I doing wrong here? I'm hoping this is not a container bug...

You cannot access the #SessionScoped bean in the #ViewScoped constructor. The #SessionScoped bean will be set AFTER the constructor of the #ViewScoped bean has been called.
Use the #PostConstruct annotation in some kind of init method to access the #SessionScoped bean.
public ViewBean() {
System.out.println("Constructor viewbean");
}
#PostConstruct
public void init() {
sessionBean.sayHello();
}
Further Links:
Why use #PostConstruct?
Spring Injection - access to the injected object within a constructor

Related

JSF application scoped bean not injectable as managed property of ADF request scoped bean

EDIT: This is an ADF application which uses JSF 2.0.
I have an application-scoped managed bean which I am referencing in the managed property of a request-scoped bean. I am getting a NullPointerException when trying to access the app-scoped bean within the PostConstruct method of the request-scoped bean. I am not sure whether I am not understanding some fundamentals about when an app-scoped bean is available to a request-scoped bean, or whether I just have a mistake in my implementation.
App-scoped bean:
#ManagedBean(eager=true)
#ApplicationScoped
public class SecurityApplication {
public String test() {
return "test result";
}
#PostConstruct
public void init() {
System.out.println("In SecurityApplication.init");
}
}
EDIT: This is configured as a request-scoped managed bean in the adfc-config.xml file. This appears to be the problem since I have specified that the bean be managed by ADF, but used the JSF ManagedProperty annotation.
Request-scoped bean:
public class UserSecurityCompanies {
#ManagedProperty(value="#{securityApplication}")
private SecurityApplication securityApplication;
#PostConstruct
public void init() {
System.out.println("In UserSecurityCompanies.init");
System.out.println("SecurityApp.Test():" + getSecurityApplication().test());
}
public SecurityApplication getSecurityApplication() {
return securityApplication;
}
public void setSecurityApplication(SecurityApplication securityApplication) {
this.securityApplication = securityApplication;
}
}
The app-scoped bean is initialized during deployment of the app, but the NPE is thrown when getSecurityApplication().test() is called.
Steve

annoted Bean not getting injected with EJB and JSF

I am nea to EJB3 and JSF. I am facing issue with bean injection and getting NullPointerException.
I have twi different modules - EJB & WEB
EJB Module has below class:
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class TestFacadeBean implements TestFacade {
.........
....
}
#Local
public interface TestFacade {
........
}
I am using this bean in my WEB module as below:
public class UserBean {
#EJB
private TestFacade testFacade;
public void useBean(){
testFacade.use();//this throws NullPointerException
}
}
UserBean is configured in faces-config.xml
<managed-bean>
<description>User Bean</description>
<managed-bean-name>userBean</managed-bean-name>
<managed-bean-class>com.test.managed.UserBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
I tries to check value for bean testFacade and found it is null. Bean is not getting set.

Get Session Scoped Bean data in another ManagedBean

I am trying to get session scoped bean data in another Managed bean. When I am doing that value is coming as null and giving java.lang.NullPointerException error. I am new to JSF so keep in mind that I might be missing simple thing.
Here is the SessionScoped Bean
#ManagedBean
#SessionScoped
public class UserSessionBean {
private superProcessId;
//getter setter and other code
}
Here is the Managed Bean I am trying to get this data
#ManagedBean
public class AddProcessBean {
#ManagedProperty(value="#{UserSessionBean}")
private UserSessionBean sessionData;
//Getter Setter for sessionData
public UserSessionBean getSessionData() {
return sessionData;
}
public void setSessionData(UserSessionBean sessionData) {
this.sessionData = sessionData;
}
public void addAction() {
System.out.println(getSessionData().getSuperProcessId());
}
}
Your value is not good in #ManagedProperty. Use:
#ManagedProperty(value="#{userSessionBean}")
Default name for bean is same as class name with lower first letter. Also scope of your bean whose managed property is should be session or lower (view, request).

EJB method is not calling from constructor

I created an ejb
#Stateless
#LocalBean
public class BasitBean {
public String helloBasit() {
return "Basit";
} //end of helloBasit()
} //end of class BasitBean
I am calling it from JSF like
<h:body>
<h:outputLabel value="#{helloBasit.callBasit()}" />
</h:body>
#ManagedBean
#SessionScoped
public class HelloBasit {
#EJB
private BasitBean basitBean;
/** Creates a new instance of HelloBasit */
public HelloBasit() {
}
public String callBasit() {
return basitBean.helloBasit();
} //end of callBasit()
} //end of class HelloBasit
This code is working fine. But when i change the code like this
<h:body>
<h:outputLabel value="#{helloBasit.label}" />
</h:body>
#ManagedBean
#SessionScoped
public class HelloBasit {
#EJB
private BasitBean basitBean;
String label;
/** Creates a new instance of HelloBasit */
public HelloBasit() {
System.out.println();
String label = basitBean.helloBasit();
System.out.println(label);
}
public BasitBean getBasitBean() {
return basitBean;
}
public void setBasitBean(BasitBean basitBean) {
this.basitBean = basitBean;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
} //end of class HelloBasit
Then i get the exception
SEVERE: Error Rendering View[/index.xhtml]
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: pk.mazars.basitMahmood.HelloBasit.
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:193)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
......
Why i am getting this exception? The flow should be what i understand is when my page encounters #{helloBasit.label} then my constructor get call, instance variable get initialized, injected the bean instance into the basitBean, then the bean method should call. But i am getting null in the bean instance in this case why? Why previous code is working and it is not ? How can i call bean from the constructor ?
Thank you.
try to move your content of the constructor into a post constructor instead...
like this
#PostConstruct
private void init() {
System.out.println();
String label = basitBean.helloBasit();
System.out.println(label);
}
Cause the ejb bean should be injected only after the managed bean has been initiated
The #PostConstruct is being run after the constructor (after that the managed bean itself was created by the JSF) and only then the EJB is being injected into the bean and can be accessed...
Your idea is correct, but I see some things that may be fixed.
#LocalBean annotation is not required if your EJB is not directly implementing an interface. In this case, with or without the #LocalBean annotation you have the same effect. You may leave that if you want to make it explicit though. See this.
Make sure both #ManagedBean and #SessionScoped import from javax.faces.bean package.
Please, see this working sample:
EJB
import javax.ejb.Stateless;
#Stateless
public class PersonService {
public String getName() {
return "Cloud Strife";
}
}
Managed Bean
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class PersonBean {
#EJB
private PersonService ps;
private String name;
#PostConstruct
public void init() {
name = ps.getName();
}
public String getName() {
return name;
}
}
XHTML Page
<?xml version="1.0" encoding="UTF-8"?>
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:view contentType="text/html">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h1>Welcome, #{personBean.name}</h1>
</h:body>
</f:view>
</html>
If your value should be loaded only once, say at your bean construction, always prefer a method with #PostConstruct annotation instead of the constructor.
Also, in order to call bean methods before rendering a view you could use a f:event tag, for example:
<f:event type="preRenderView" listener="#{personBean.init}" />
I hope it helps!

How to inject a value to a sub-property of a bean (without annotations)?

I want to ask you if it is possible to inject a value to a sub-property of a bean.
This is what I want to do, but Eclipse IDE complains with:
Bean property beanB.subprop not found on parent class paq.paq.BeanA
<managed-bean>
<managed-bean-name>beanA</managed-bean-name>
<managed-bean-class>paq.paq.BeanA</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>beanB.subprop</property-name>
<value>Hello!</value>
</managed-property>
</managed-bean>
public class BeanA implements Serializable {
public BeanB beanB = null;
public Skin getBeanB() {
if (this.beanB == null) {
this.beanB = new BeanB();
}
return this.beanB;
}
public void setBeanB(BeanB beanB) {
this.beanB = beanB;
}
}
public class BeanB implements Serializable {
public String subprop = null;
public String getSubprop() {
return this.subprop;
}
public void setSubprop(String subprop) {
this.subprop = subprop;
}
}
Thanks!
Every nested bean needs to be declared as a managed bean as well. You need to inject it on the nested bean instead and then inject the nested bean itself in the main bean.
<managed-bean>
<managed-bean-name>beanA</managed-bean-name>
<managed-bean-class>paq.paq.BeanA</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>beanB</property-name>
<value>#{beanB}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>beanB</managed-bean-name>
<managed-bean-class>paq.paq.BeanB</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>subprop</property-name>
<value>Hello!</value>
</managed-property>
</managed-bean>

Resources