Inject EJB bean from JSF managed bean programmatically - jsf

I have EJB stateless bean.
How can I inject it to JSF managed bean by programmatic instead of #EJB annotation?

You can't inject it programmatically. You can however obtain it programmatically. EJBs are also available via JNDI. Usually, you find those JNDI names/aliases printed in server startup log. At least JBoss / WildFly does that.
There are different JNDI name aliases:
java:global/APP_NAME[/MODULE_NAME]/EJB_NAME
java:app/MODULE_NAME/EJB_NAME
java:module/EJB_NAME
Where /APP_NAME is the name of the WAR or EAR application, and /MODULE_NAME is the name of the EJB module in case of an EAR application, or the WAR module in case of a single-WAR application (and this will be absent in java:global as it otherwise repeats /APP_NAME), and /EJB_NAME defaults to the class name of the EJB class.
The java:global is accessible through the entire server. The java:app is only accessible from inside the same application (WAR or EAR). The java:module is only accessible from inside the same module (EJB in case of EAR or WAR itself in case of single-WAR).
A JSF managed bean is obviously inside a WAR. If you've a single-WAR application, then java:module/EJB_NAME must work. If you've however an EAR project, then the EJB is obviously inside the EJB module, in that case the java:module won't work and you'd need java:app or java:global.
So, given an EJB like below,
#Stateless
public class FooService {}
it's in a single-WAR project named "foo_war" via JNDI available in a JSF managed bean as follows (usually you do that in #PostConstruct method):
InitialContext jndi = new InitialContext();
FooService fooService = (FooService) jndi.lookup("java:module/FooService");
// Or
FooService fooService = (FooService) jndi.lookup("java:app/foo_war/FooService");
// Or
FooService fooService = (FooService) jndi.lookup("java:global/foo_war/FooService");
or in an EAR project named "foo_ear" with an EJB module named "foo_ejb" with therein the EJB class (while the JSF managed bean is in the WAR module of the EAR project):
InitialContext jndi = new InitialContext();
FooService fooService = (FooService) jndi.lookup("java:app/foo_ejb/FooService");
// Or
FooService fooService = (FooService) jndi.lookup("java:global/foo_ear/foo_ejb/FooService");

Related

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?

Injecting a remote EJB in a managedBean

I'm stuck since x time on how to inject a remote EJB in a managed bean of a JSF application.
I've created a simpl java application and i've come to inject the remote EJB with the lookup... and it works.
but when i come to the web application i really don't know what to do !!!
here is my EJB code:
#Stateless
public class Hello implements HelloRemote {
#Override
public String sayHello(String name) {
return "Hello, "+name;
}
}
the Remote interface is
#Remote
public interface HelloRemote {
public String sayHello(String name);
}
in my web application i vre created i managed bean :
#ManagedBean
public class MyBean {
#EJB
HelloRemote helloRemote;
}
BUT IT DOESN'T WORK :(
If you want to expose EJB locally you have to use #Local on Interface.
If you want to expose both locally and remotely you have to created 2 Interfaces, one with #Local and one with #Remote.
If your JSF ManagedBean(MyBean) is running locally ie.,Running on same App server as EJB you can directly inject it using #EJB.
If your JSF ManagedBean is running on different server, you have to use the JNDI Registry to look up and access the EJB.

Update faces-config.xml in memory at runtime

When a JSF/XPages application starts it reads the faces-config.xml for managed beans, validators etc. Can I manipulate the loaded configuration at runtime? e.g. dynamically add a validator to ensure my custom code will run.
I'm not trying to change the xml file at runtime, but the memory representation after it gets loaded.
XPages uses a JSF 1.x runtime,so JSF 2.0 constructs might not work
Yes, you can add a lot of JSF artifacts which are normally configured in faces-config.xml by among others the Application class as well.
Application application = FacesContext.getCurrentInstance().getApplication();
application.addValidator("fooValidator", "com.example.FooValidator");
// ...
You could do the job in an eagerly initialized application scoped managed bean.
#ManagedBean(eager=true)
#ApplicationScoped
public class Config {
#PostConstruct
public void init() {
// ...
}
}

Inject EJBs into a Seam Component

guys. I have a Seam project running on Tomcat 6.0.20 (webapp.war) and an EJB project running on JBoss 4.2.3 (ejbapp.ear).
I can access my EJBs in my Seam components using JNDI lookup [initialContext.lookup(...)].
I'd like to have them injected in my Seam components instead.
My Seam components ARE NOT EJBs, so I can't use #EJB annotation. I'd like to have something like this in my Tomcat (Web) app.
#Name("customerAction")
public class CustomerAction {
#In // even with (autoCreate=true) or the EJB name if necessary
private CustomerEJB customerEJB;
...
}
And this in the JBoss (EJB) app.
#Stateless(name="customerEJB")
public class CustomerEJBImpl implements CustomerEJB {
...
}
#Remote
public interface CustomerEJB {
...
}
In my components.xml I have the jndiPattern=ejbapp/#jndiPattern/remote specified just like I currently use to lookup the EJBs (ex: ejbapp/CustomerEJB/remote).
I'm probably missing something in my configuration to make this work.
PS: I'd like NOT HAVE to annotate my EJBs as #Name (Seam) components.
Any suggestions? Thanks in advance.
Thanks for your reply, but it didn't work.
When I declared the EJBs in components.xml, it did inject the object in my Action (Seam component), but as a POJO. I mean, the EntityManager and other EJB injections I had in the injected object didn't work.
I also tried to define the EJB as a Seam component, but, once they are in the webproject inside a JAR file, it didn't load automatically, and trying the scenario above, I got the same error.
Just an FYI, I also declared the Seam interceptor in ejb-jar.xml file.
I have no idea why this is happening, BTW I thought it would be quite a simple thing for Seam to handle.
Anyway..., any other suggestions, guys?
Define your EJB as Seam components in your components.xml

Seam - EJB3 in Web Module/WAR?

I'm writing an application using Seam 2.2.x which will be deployed on JBoss 5.1. I have an EJB module with all of the business logic en EJB's. However, I'd also like to have statless session EJBs in the web module to act as action classes. Is this possible? Do I need to perform any additional configuration to get this working? I have an interface I've defined:
#Local
public interface ContentItemSearchAction extends Serializable {
...
}
...and an implementing class...
#Name("contentItemSearchAction")
#AutoCreate
#Stateless
public class ContentItemSearchActionBean implements ContentItemSearchAction {
...
}
However, when I try to access the EJB in one of my JSF views, I get the following exception:
Caused by javax.naming.NameNotFoundException with message: "ContentItemSearchActionBean not bound"
Has anyone seen this before? What am I missing? Why is the EJB in my WAR module not being picked up?
EJBs do not go into WAR files. They're packaged into JARs, which go into the EAR along with the WAR.
The EJBs need not be in the WAR to be visible from your web tier.

Resources