Inject an EJB into a JSF managed bean - jsf

I have a war application with some JSF managed beans and EJB for some business logic. I'm using JSF 1.2, JBoss 5 and java 1.6
My managed bean:
#ManagedBean(name = "managedBean")
#SessionScoped
public class MyManagedBean implements Serializable {
#EJB(mappedName = "ejbBean")
public MyEjbBean ejbBean;
....
}
EJB bean:
#Singleton(name = "ejbBean")
public class MyEjbBean {
....
}
Page not rendered, error:
javax.naming.NamingException: Could not dereference object [Root exception is javax.naming.NameNotFoundException: ejb not bound]
What am I doing wrong?

JBoss 5 doesn't support #Singleton EJB (added in EJB3.1 spec), you can use the JBoss #Service annotation to create a singleton.
See the instructions here.

Related

How to set #ManagedProperty in CDI

recently I was migrating JSF managed beans to CDI managed beans, but now I need to set a property from one bean to another in CDI, I mean how to adapt the annotation #ManagedProperty(value="#{articleBean.cverev}") using CDI. A fragment of my code is:
#Named
#SessionScoped
public class UserBean implements Serializable{
#Inject #Named
private ArticleBean articleBean;
/*In this part*/
#ManagedProperty(value="#{articleBean.cverev}")
private long cverev;
How can I do it?

Why is a CDI Managed Bean in faces-config.xml not registered as an obersver?

I have implemented a CDI Bean which is observing events from another bean:
#SessionScoped
public class FixedItemController implements Serializable {
....
public void onWorkflowEvent(#Observes WorkflowEvent workflowEvent) throws AccessDeniedException {
logger.info("evaluate event...");
....
}
....
}
This works fine as long as I am using the bean in a JSF page with its default name 'fixedItemController'.
But if I declare another instance of that bean in the faces-config.xml like this:
<managed-bean>
<managed-bean-name>myOrderItemController</managed-bean-name>
<managed-bean-class>org.imixs.marty.workflow.FixedItemController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>childItemProperty</property-name>
<property-class>java.lang.String</property-class>
<value>_orderItems</value>
</managed-property>
</managed-bean>
the second instance (myOrderItemController) is not registered automatically as an observer for my WorkflowEvent.
What can I do, to ensure that my second instance - declared by the faces-config.xml - will be immediately instantiated and registered as an observer to my workitemEvent?
faces-config.xml does not register CDI managed beans. It registers JSF managed beans. Effectively, your #{myOrderItemController} is a JSF managed bean. It's like as if you use #ManagedBean instead of #Named. The JSF bean management facility does not scan for CDI specific #Observes annotation.
Keep it a CDI managed bean. Whatever you tried to solve for which you thought that registering it in faces-config.xml would be the right solution has to be solved differently using the CDI API instead of the JSF API.

Inject an application scoped managed bean in a websocket

I'm developing a real time application. I have websockets and application scoped managed bean. I'm trying to access the application scoped managed bean from a websocket but I can't. Is this possible?
This is my websocket and managed bean (application scoped):
#ServerEndpoint("/mediador")
#ManagedBean(eager = true)
#ApplicationScoped
public class Mediador implements Serializable {
#ManagedProperty(value = "#{aplicacion}")
private Aplicacion aplicacion;
...
And my "Aplicacion" managed bean:
#ManagedBean(eager = true)
#ApplicationScoped
public class Aplicacion implements Serializable {
...
If I try to access in Mediador class to de managed property "aplicacion" it's null so I get a NullPointerException.
Thanks
This is really not right.
#ServerEndpoint("/mediador")
#ManagedBean(eager = true)
#ApplicationScoped
public class Mediador implements Serializable {
WS (JSR-356 WebSocket) API and JSF API are completely independent from each other. They know nothing from each other and won't take mixed annotations from each other into account.
Effectively, you end up with two instances of the class. One as a WS managed server endpoint as available by ws://.../mediador, and one as a JSF managed bean as available by #{mediador}. The #ManagedProperty is only recognized by JSF managed bean facility and it'll work in the JSF managed bean instance only.
Use CDI instead. It works across the entire Java EE web application. Not only in WebSocket endpoints, but also in JSF managed beans, WebServlets, WebFilters, WebListeners, JAX-RS resources, JAX-WS resources, etcetera. Eventually, JSF managed bean facility will be deprecated in favor of CDI. This will happen in Java EE 9 or perhaps already 8.
#ServerEndpoint("/mediador")
public class Mediador { // Shouldn't be serializable!
#Inject
private Aplicacion aplicacion;
// ... (no getter+setter needed!)
}
#Named
#ApplicationScoped // javax.enterprise.context
public class Aplicacion { // Shouldn't be serializable!
// ...
}
Unrelated to the concrete problem: implementing websockets in JSF rightly is not exactly trivial, certainly not if you'd like to take into account JSF session and view scopes, and would like to be able to target a specific user during push. You'd better look at an existing push component. See also How can server push asynchronous changes to a HTML page created by JSF?

Is it possible intercept a method from #ManagedBean? If not, there alternatives?

I'm new to JSF-2 and CDI (I'm from Spring world).
I want to intercept a method from #ManagedBean but my Interceptor class is never called. Is it possible to do?
LogInterceptor.java
#Interceptor
public class LogInterceptor {
#AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("begin method interceptor");
Object methodReturn = ctx.proceed();
System.out.println("end method interceptor");
return methodReturn;
}
}
RoleMB
#ManagedBean
#ViewScoped
public class RoleMB extends BaseMB {
#Interceptors(LogInterceptor.class)
public void preEditRole(Role role) {
...
}
}
beans.xml
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>br.com.preventsenior.services.log.LogInterceptor</class>
</interceptors>
</beans>
The log(InvocationContext ctx) is never called.
Java EE interceptors work only on CDI managed beans and EJBs, not on JSF managed beans.
So, you've basically 2 options:
Change JSF bean management annotations by CDI bean management annotations (#Named et.al.)
Intercept on an EJB method instead which is in turn invoked by JSF managed bean. In a sane Java EE application, the real business logic belongs in EJBs anyway.

JSF2.0 PostConstructApplicationEvent managed bean is null

We have JSF2.0 in Tomcat6.0 , need to initialize a ApplicationScope Bean while web server is started.
I tried using the PostConstructApplicationEvent processEvent method to initialize the Bean , but the managed bean from faces-config.xml is returning null.
Is there any other better way to instantiate the bean after startup?
Remove any faces-config.xml declarations related to the bean (they will otherwise override the JSF 2.0 annotations) and then annotate the bean with #ManagedBean(eager=true) as follows:
#ManagedBean(eager=true)
#ApplicationScoped
public class Bean {
// ...
}
This way the bean will always be instantiated on JSF webapp startup, without the need to view any page. You can then do the initialization job in the constructor and/or #PostConstruct of the bean.

Resources