I'm having a problem instantiating a stateful session bean on glassfish3.1.
A #ManagedBean (session scoped) of a JSF application used to use a #Local interface of a #Stateless session bean and everything worked fine.
Now I had to convert to a #Stateful bean and I'm getting an exception when I try to inject the stateful bean into the mannaged bean.
The code in question consists of the following 3 layers:
#ManagedBean
#SessionScoped
public class ShopBean {
private #EJB ShopAdminInterface sa;
...
}
#Local
public interface ShopAdminInterface {
.... some interfaces
}
#Stateful
public class ShopAdmin implements ShopAdminInterface {
#EJB CoreClassEAO s;
... some implementation
}
The CoreClassEAO presents an access layer to the database and looks like this:
#Stateful
public class CoreClassEAO {
#PersistenceContext
EntityManager em;
.... access to my persistence interface
}
In the last version, when the ShopAdmin and CoreClassEAO both were #Stateless beans everything worked perfectly. But now, injecting ShopAdminInterface throws an exception at me
Update: I narrowed down the problem: See my other question
Injecting #Stateful bean into another #Stateful bean
Related
I have a class like this,
#Component
class GenericRepositoryModel<T>
{
//.,..
}
In my code, I have to use for a specific type,
#Controller
class WebController
{
#Autowired
private GenericRepositoryModel<Type1> customerRepository;
}
But when I try to do the above, I am getting the below exception.
Field customerRepository in com.sbexample.springbootdemo.WebController
required a bean of type
'com.sbexample.springbootdemo.GenericRepositoryModel' that could not
be found. Consider defining a bean of type
'com.sbexample.springbootdemo.GenericRepositoryModel' in your
configuration.
What's the right way of doing it?
BTW, I am using Spring 4.3.16 via Spring boot 1.5.10.
Here is backing bean of my log in page. Why does it preserve values after calling the logIn() method? I mean after I submit the form and return to the login page my previously entered username is already there. I thought that by using #RequestScoped annotation the values are not preserved.
#Controller
#ManagedBean
#RequestScoped
public class LogInBean implements Serializable {
private static final long serialVersionUID = 2092611147930386873L;
#Autowired
private UserService userService;
private String username;
private String password;
private boolean rememberMe;
public String logIn() {
return "index?faces-redirect=true";
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isRememberMe() {
return rememberMe;
}
public void setRememberMe(boolean rememberMe) {
this.rememberMe = rememberMe;
}
}
It's because you're actually using an application scoped Spring managed bean instead of a request scoped JSF managed bean.
Your main mistake is that you're mixing JSF bean management annotations with a Spring bean management annotation and somehow are expecting that they seamlessly understand each other.
#Controller
#ManagedBean
#RequestScoped
This is thus not true. You effectively end up with two completely independent managed bean instances, one managed by JSF and another managed by Spring. The #RequestScoped annotation is specific to JSF bean management facility. The Spring's equivalent, #Scope("request") is absent and therefore the Spring managed bean defaults to the application scope. When referencing the bean in EL scope like so #{logInBean}, the Spring managed one gets precedence over JSF managed one because of the Spring bean EL resolver and you ultimately end up with an application scoped Spring managed bean. This totally explains the symptoms.
Fix it accordingly by getting rid of JSF bean management annotations and placing the desired Spring scope annotation:
#Controller
#Scope("request")
(an alternative would be to get rid of Spring bean management annotation and replace #Autowired by #EJB, like as one would normally do when using standard Java EE stack without any 3rd party library)
If you still face this problem, then another possible cause would be that you're submitting the login synchronously while not having autocomplete="off" on the input fields, head to this Q&A then: Disable web browser password save.
In my JSF2-Primefaces3 webapplications I am referencing beans named "HomeBean" from bean "CityBean" I am using ManagedBean annotations and DO NOT have faces-config.xml at all. Please find the code as below:
HomeBean
#ManagedBean(name="HmBen")
#SessionScoped
public class HomeBean implements Serializable {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(HomeBean.class);
private List<Offer> offersList;
public HomeBean() {
}
}
CityBean
#ManagedBean(name="CtyBen")
#SessionScoped
public class CityBean implements Serializable {
private static final long serialVersionUID = 1L;
#ManagedProperty(value="#{HmBen}")
private HomeBean homeBean;
public CityBean() {
}
/**
* Following setters are required as per the documentation for Dependancy
* Injection of beans to work
*/
public void setHomeBean(HomeBean homeBean) {
this.homeBean = homeBean;
}
}
NOTE: this is just a section of the code due to character limits imposed by Stackoverflow.
I am getting following exception:
Caused by: com.sun.faces.mgbean.ManagedBeanCreationException: Unable to set property homeBean for managed bean CtyBen
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:615)
at com.sun.faces.mgbean.ManagedBeanBuilder.buildBean(ManagedBeanBuilder.java:133)
... 20 more
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:2377)
Does anyone has any clue about this?
Response already committed let me explain what does it mean. on page rendering it is rendering from top to bottom. Server giving response in bytes. after rendering some bytes server gets notification(some if condition on page) that's now you have to render bytes at that time server can not take bytes which already sent to user at that time Server throwing IllegalState exception. Give your .xhtml page. please check following question posted by me a year ago.
Jsf2.0 forwarding page error without parameter
i have a strange behaviour in my app:
I use a SessionScope bean (Bean A) to hold users preferences. In my other Bean (Bean B), which is in RequestScope, I inject the SessionScope bean.
Bean B has a #PostConstruct method to retrieve a list of values from the database depending on the value in Bean A. The application gets confused when the user changes the value in Bean A and its value in Bean B is not correct at the time #PostConstruct method is invoked. I tested it with logs.
I think all setter methods will be updated before Invoke Application Phase?
Here is a code sample:
Bean A:
#Named
#SessionScoped
public class SessionBean implements Serializable {
private static final long serialVersionUID = -4214048619877179708L;
#Inject private Logger log;
private BankAccount selectedBankAccount;
public BankAccount getSelectedBankAccount() {
return selectedBankAccount;
}
public void setSelectedBankAccount(BankAccount selectedBankAccount) {
log.info("ba: " + selectedBankAccount);
this.selectedBankAccount = selectedBankAccount;
}
Bean B:
#RequestScoped
public class SubAccountListProducer {
#Inject private SessionBean sessionBean;
#Inject private EntityManager em;
#PostConstruct
public void retrieveAllSubAccount() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<SubAccount> criteria = cb.createQuery(SubAccount.class);
Root<SubAccount> account = criteria.from(SubAccount.class);
log.info("retrieveAllSubAccount: " + sessionBean.getSelectedBankAccount());
criteria.select(account).where(cb.equal(account.get("bankAccount"), sessionBean.getSelectedBankAccount()));
criteria.select(account).orderBy(cb.desc(account.get("name")));
entityList = em.createQuery(criteria).getResultList();
}
Sample logs:
ba: BankAccount [accountId=123456789, bankName=Ing DiBa, blz=50010517]
retrieveAllSubAccount: BankAccount [accountId=123456789, bankName=Ing DiBa, blz=50010517]
retrieveAllSubAccount: BankAccount [accountId=123456789, bankName=Ing DiBa, blz=50010517]
ba: BankAccount [accountId=987654321, bankName=Barclaycard Barclays Bank, blz=20130600]
As you can see... the first two logs are correct... if the user changes preferences (updates the SessionBean), the view will be rerendered with JSF and the last two logs are not in correct order and my app gets confused.
Thank you for help.
The #PostConstruct is not executed during invoke action phase. It is executed directly after bean's construction. The PostConstruct should only be used to preinitialize some stuff depending on injected dependencies directly after bean's construction. Because your bean is request scoped instead of conversation scoped (or view scoped), it will be constructed on every single request.
You need to do the updating/refreshing job in the real action method instead, which is the method you've specified in the <h:commandButton>/<h:commandLink>. E.g.
<h:commandButton value="Submit" action="#{bean.submit}" />
with
public void submit() {
// ...
retrieveAllSubAccount();
}
I also suggest to put your bean in the CDI conversation scope or JSF view scope, so that it don't unnecessarily get reconstructed on every postback to the same view.
Currently I am trying to inject a stateless EJB into a CDI managed controller on Jboss 6 AS Final. The controller is managed in the context an accessible from the JSF pages. If I inject the stateless bean with #EJB it is working. If I inject the stateless EJB with #Inject I get the following Exception:
My controller:
#Named("TestController")
public class TestController {
#Inject
private TestManagerLocal myTestManager;
...
}
}
My stateless bean:
#SuppressWarnings("unchecked")
#Stateless
public class TestManagerBean implements TestManagerLocal {
#PersistenceContext
private EntityManager em;
...
}
The Interface of the Bean is annotated with #Local.
If I try to call myTestManager I get the following exception:
WELD-000079 Could not find the EJB in JNDI: class
de.crud.org$jboss$weld$bean-jboss$classloader:id="vfs:$$$usr$local$jboss$server$default$deploy$test$ear"-SessionBean-TestManagerBean_$$_WeldProxy
THX a lot.
For those not having the luxury to change an ear to a war, I've found the following workaround:
Create an EJB in the war
Inject that EJB with the EJBs from the EJB module
Add CDI producer methods
Qualify #Inject with the qualifier for those producer methods:
Code:
// This bean is defined in the WEB module
#Stateless
public class EJBFactory {
#EJB
protected UserDAO userDAO;
// ~X other EJBs injected here
#Produces #EJBBean
public UserDAO getUserDAO() {
return userDAO;
}
// ~X other producer methods here
}
Now EJBs from anywhere in the EAR can be injected with:
// This bean is also defined in the web module
#RequestScoped
public class MyBean {
#Inject #EJBBean
private UserDAO userDAO; // injection works
public void test() {
userDao.getByID(...); // works
}
}
EJBBean is a simple standard qualifier annotation. For completeness, here it is:
#Qualifier
#Retention(RUNTIME)
#Target({TYPE, METHOD, FIELD, PARAMETER})
public #interface EJBBean {
}
The problem was, that I built and deployed my application as an ear. Weld is working when I deploy my application as an war including all EJBs.
Currently there are various problems arising from the fact that WARs in EAR-Deployments don't share the same classloader. See https://issues.jboss.org/browse/JBAS-8683 for the ongoing discussion in the JBoss-AS JIRA (and vote it up :-) )
UPDATE I found this information on how to disable separate classloaders, option 1 worked for me, but be extremely careful with this. The separation of classloaders hasn't been introduced for no reason, so apparently there are new problems on the road ahead...