Is it safe to store pending executions list in context of a user's actions within a web app in a session scoped bean & then reliably execute those actions at the end of session through #Predestroy annotated method(i mean, safety in context of #predestroy method not getting called & thus action not being executed under some circumstances or so !? ).
you might want to look at moving your logic to a HttpSessionListener implementation (it's an interface). you would trigger on sessionDestroyed events (via implementing that method in your concrete implementation).
it's pretty easy, to use and a great spot to handle this kind of thing (i implemented one in a current product as a JMX bean to handle controlling sessions at runtime).
TIA
It's completely safe to store the pending executions or DB commits in the #preDestroy method. In this state there the Managed bean will not be destroyed. So the state of the managed bean will be same as it is a normal method call inside the bean. Please refer below documentation.
http://docs.oracle.com/javaee/6/tutorial/doc/gmgkd.html#gmghg
"To Prepare for the Destruction of a Managed Bean Using the #PreDestroy Annotation
Preparing for the destruction of a managed bean specifies the lifecycle call back method that signals that an application component is about to be destroyed by the container.
In the managed bean class or any of its superclasses, prepare for the destruction of the managed bean.
In this method, perform any cleanup that is required before the bean is destroyed, such as releasing a resource that the bean has been holding.
Annotate the declaration of the method with the javax.annotation.PreDestroy annotation.
CDI calls this method before starting to destroy the bean."
Related
Do you think it is a good idea to put all widely used utility methods in an application scoped bean?
In the current implementation of the application I'm working on, all utility methods (manipulating with Strings, cookies, checking url, checking current page where the user is etc.) are all put in one big request scoped bean and they are referenced from every xhtml page.
I couldn't find any information on stackoverflow if the approach of putting utility methods in an application scoped bean would be a good or a bad choice.
Why I came across this idea is the need of reusing those methods in a bean of a wider scope then a request scoped bean (like view or session scoped bean). Correct me if I'm wrong but you should always inject same or wider scoped beans i.e. you shouldn't inject request scoped bean inside a view scoped one.
I think using utility methods from application scoped bean should be beneficial (there won't be any new object creations, one object will be created and re-used across all application), but still I would like a confirmation or someone to tell me if that is a wrong approach and why is it wrong.
As to the bean scope, if the bean doesn't have any state (i.e. the class doesn't have any mutable instance variables), then it can safely be application scoped. See also How to choose the right bean scope? This all is regardless of the purpose of the bean (utility or not). Given that utility functions are per definition stateless, then you should definitely be using an application scoped bean. It saves the cost of instantiating on every single request.
As to having utility methods in a managed bean, in object oriented perspective this is a poor practice, because in order to access them from EL those methods cannot be static while they should be. You can't use them as real utility methods in other normal Java classes. Static code analyzers like Sonar will mark them all with a big red flag. This is thus an anti-pattern. The correct approach would be to keep using a true utility class (public final class with private Constructor() with solely static methods) and register all those static methods as EL functions in your.taglib.xml as described in How to create a custom EL function to invoke a static method?
At least, this is what you should be doing when you intend to have a publicly reusable library such as JSTL fn:xxx(), PrimeFaces p:xxx() or OmniFaces of:xxx(). If you happen to use OmniFaces, then you could, instead of creating a your.taglib.xml file, reference the class in <o:importFunctions>. It will automatically export all public static methods of the given type into EL function scope.
<o:importFunctions type="com.example.Utils" var="u" />
...
<x:foo attr="#{u:foo(bean.property)}" />
If you don't use OmniFaces, and this all is for internal usage, then I can imagine that it becomes tiresome to redo all that your.taglib.xml registration boilerplate for every tiny utility function which suddenly pops up. I can rationalize and forgive abusing an application scoped bean for such "internal usage only" cases. Only when you start to externalize/modularize/publicize it, then you should really register them as EL functions and not expose poor practices into public.
I need to call a method annotated with #Asynchronous in EJB from a ConversationScoped bean. Inside this method I create instances of some classes using #Inject to inject ConversationScoped beans.
Is it somehow possible to set the context of the asynchronous method to given Conversation?
I hope you can help me.
No, absolutely not. EJBs do per definition not run in web container, but in EJB container. In essence, having any web-related artifact/dependency (including javax.faces.* classes) inside an EJB class is a red alert. You're not supposed to inject/access any class from the client tier (the WAR) in the business tier (the EJB/EAR). Moreover, conversation scoped beans are tied to a HTTP request parameter and this information is nowhere available in an EJB container.
Whatever problem you're trying to solve and for which you incorrectly thought that this all would be the right solution, it has to be solved differently. As an educated guess, I think you just need to let the EJB fire a CDI event or take a callback argument.
See also:
JSF Service Layer
I'm working with JSF 2.0 and and existing framework. We have a listener class that allows us to see when objects are being added to the request/session by implementing HttpSessionAttributeListener and ServletRequestAttributeListener.
Now that we are dealing with #ViewScoped objects I can't figure out a way to get alerted when a ViewScoped object is added. Is there a new listener for this similar to the 2 mentioned above?
The view scope is represented by UIViewRoot#getViewMap(). This map only fires the creation and destroy events, the PostConstructViewMapEvent and PreDestroyViewMapEvent respectively, which can be listened by a ViewMapListener implementation (which is by the way quite verbose to set up as compared to e.g. HttpSessionBindingListener; the JSF system event listener API is not really well thought out as to configuration). This map does not fire any events for add/remove. To be sure, I even looked in source code of Mojarra if it didn't sneakily do that, but, unfortunately, it doesn't.
Your best bet is to fire those add/remove events manually in #PostConstruct and #PreDestroy of your view scoped beans. Noted should be that in JSF 2.0/2.1 the #PreDestroy of a view scoped isn't invoked on a session expire. This was an oversight in the spec and is fixed for JSF 2.2.
I want a method in a session scoped backing bean to be called after a user logs in. How can I do that?
Environment: Spring Security 3.0.x, Spring 3.0.x and JSF 1.2. The backing beans are managed by Spring.
Background: Sessions are created even without login. My session scoped bean holds settings, that are initially set to default values. After login I want to update the session state to the preferences stored in the database for that particular user. To achieve that I imagined an interface or even simpler an annotated (e.g. #PostLogin) method, but so far I have not found anything like that.
It would be OK if that method is called on every principal change, i.e. also on logout. It would also be acceptable if the whole bean is destructed and recreated on login, though my other session scoped beans should survive.
What I have found so far is:
ApplicationListener<AuthenticationSuccessEvent>: The listener apparently needs to be application scoped, and I can't get access to my session scoped bean in it. #Autowired plus scope proxy don't work. The injected object is broken; it does not contain its dependencies although the real backing bean does.
<form-login authentication-success-handler-ref="..">: haven't tried this, but I need the method to be called independent of the used login procedure. Other than form based we support remember me and programmatic login (e.g. automatically logged in after password forgotten process).
Answering my own question:
ApplicationListener was the right track, however #Autowired was not.
I defined an interface with one method, that is implemented by my session scoped bean. The (singleton scoped) event listener class then uses ApplicationContext.getBeansOfType(..) to find the session beans by that interface and invokes the interface's method on each of them.
Can anyone help me to understand the JSF managed bean scope from a concurrency perspective ?
My Understanding:
Once i have a bean scoped in a session scope that's mean : there is only one user can access this managed bean so there is no possibility to concurrency occur.
Also, once i use a bean in a request scope then this bean will be created once a request had initiated
and that bean will be removed once a response returned. (each clients have different copy of this bean)
Also, once i use a bean in a none scope then once the user call the bean it will be created and after finish the call the bean will be removed.
But once i have a bean in an application scope that's mean multiple client can access this bean, so
if i have a critical data it must be protected by synchronization.
All your inputs are highly appreciated.
I think your understanding of the lifespan of each of the scopes is fine.
However, I think your understanding of when to apply synchronization is not good. Whenever you need to synchronize the methods of a bean in a certain scope, then this is usually an indication that the scope of the bean is too wide for the data it holds. You should then put the bean in a more narrow scope or to move the data into another bean in a more narrow scope, so that synchronization is not necessary.
You should put request scoped data (presentational data, synchronous form data, etc) in the request scope. You should put view scoped data (asynchronous form data, rendered attribute conditions, "hidden" values, etc) in the view scope. You should put session scoped data (logged-in user, user preferences, user-specific data, etc) in the session scope. You should put application scoped data (global dropdown list values, configuration settings, etc) in the application scope.