Java EE 7 + GlassFish 4 - Run bean on startup - cdi

Using CDI is there a way to cause a bean to be instantiated when the application server starts up?
I would like to be able to do something like:-
#Singleton
#Startup
public class StartupBean {
...
}
Unfortunately, although the #Singleton annotation exists in the javax.inject.* package the #Startup annotation doesn't.

Use both of those from the javax.ejb.* package. EJBs support CDI and you can kick off anything you want.

Related

Get properties file from CDI bean

How can I get a properties file from CDI bean, I mean properties file for internationalization purposes as mentioned here.
In #ManagedBean everything is simple #ManagedProperty(name="....") but I can't encounter the way to achieve the same in CDI bean.
Thank you very much.
As far as I know, CDI doesn't support the kind of field-level access that #ManagedProperty gives (where you can have #ManagedProperty(name="#{msgs.title}")). If you want that level of control in CDI, you'll have to write a CDI Producer.
Considering that the resource bundle is simply a class of ResourceBundle, you could easily obtain your defined bundle with:
FacesContext ctxt = FacesContext.getCurrentInstance();
ResourceBundle bundle = ctxt.getApplication().getResourceBundle(ctxt, aValue);
bundle.get("title");
Alternatively, you could simply inject either your FacesContext or Application into your bean:
#Inject
Application theApplication
public void getBundle{
ResourceBundle bundle = theApplication.getResourceBundle(ctxt, aValue);
}
If you're looking for internationalization support within CDI for JSF purposes, you may want to look at DeltaSpike's JSF module. It builds off of the core i18n support available in core.

How to call EJB in PhaseListener

I use JSF 2 and EJB 3.1, all of them are deployed on Glassfish 3.1.
When i setup a class named MyInterceptor which is implemented PhaseListener, i can not revoke remote EJB interface inside it.
It notice "NullPointerException ..."
public class MyInterceptor implements PhaseListener {
#EJB(name="AuthorizationEJB",
beanInterface=AuthorizationService.class,
mappedName="corbaname:iiop:localhost:3700#ejb/AuthorizationEJB")
public AuthorizationService authorizationService;
....
}
When I call authorizationService.dosomestuff(), it raise error NullPointerException
How can i do to fix it?
Thank in advance
In JSF 2.1 and earlier, PhaseListeners are unfortunately no injection targets (meaning you can't use injection in them). You can do your lookup programmatically via JNDI instead though.
In JSF 2.2 all JSF artifacts (including PhaseListeners) will be injection targets, but this will probably not help you now.
Unrelated to your question, but I'm not sure what you're trying to achieve by specifying the beanInterface in your annotation. Most likely you'll also don't need the name attribute and if your bean is a local bean you'll also don't need mappedName.
Use a servlet filter instead of a JSF phase listener to do authorization. You can inject an #EJB in a #WebFilter.
Yeah in web filter you could have just used plain #EJB. Maximimum you needed to add beanName if you had two beans implement same AuthorizationService interface.
Servlet filter is per request, I don't think you need to do security stuff at a certain phase from JSF's lifecycle (which is a more granular level than the whole http request).
For normal lookup you can do:
AuthorizationService.class.cast(new InitialContext().lookup("corbaname:iiop:localhost:3700#ejb/AuthorizationEJB")).dosomestuff();
in a try catch javax.naming.NamingException

does this JSF pattern break dependency injection?

I have a JSF2 project (Mojarra on GlassFish 3.1).
I have a ViewScoped bean that references services through a utility class like so:
#ManagedBean
#ApplicationScoped
public static class ServicesUtil {
#EJB
UserService userService;
#EJB
EmailService emailService;
/** getters/setters **/
}
and
#ManagedBean
#ViewScoped
public class UserHandler {
public String method() {
ServicesUtil.getUserService().doUserStuff();
return "newPage";
}
}
My question is, since the ServicesUtil is ApplicationScoped, does that mean there is only one instance of each service for the entire application? And is this bad practice? If done correctly, would the CDI in GlassFish actually create new instances as they are needed?
Similarly, if the Services were injected into the UserHandler instead would the application be more scalable?
The reason we added the ServicesUtil layer is one of my coworkers said that he occasionally had problems getting the injection to work in the Handler when it is ViewScope. Should there be any difficulty using #EJB in a ViewScoped bean?
Any help is greatly appreciated!
Rob
The pattern you're using doesn't seem to make a lot of sense. There should be no problem with injecting EJBs into a view scoped bean.
Depending on the type of EJB you are using (stateless, stateful or singleton) different things hold.
If the userService and emailService are stateless (they most likely should be), you gain nothing by using a bean that's injected into an application scoped bean first. Namely, what's injected is not the bean itself but a proxy and every request to that is routed to a different real bean instance anyway (see http://en.wikipedia.org/wiki/Enterprise_JavaBean#Stateless_Session_Beans).
If the userService and emailService are stateful, you do get a single instance here, but I highly doubt you need to share actual between every user in your application. But even if you would want that, only a single user (thread) can access the stateful bean at a time.
If those services are singleton, you can just inject them right away into the view scoped bean. There is absolutely no reason to go via an application scoped bean.
Furthermore, ServicesUtil.getUserService() is a static method, so using this to get an injected service is brittle. If you want to use this (you shouldn't, but suppose) ServicesUtil should be injected into UserHandler.
Then, it seems you are confusing CDI and JSF managed beans. I agree this is confusing, but it's currently the way it is. #ViewScoped does not work in combination met CDI beans. From your code it's not clear if #ManagedBean is the JSF variant or the Java EE/CDI one. In this case it should be javax.faces.bean.ManagedBean if you want to use the view scope.

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