XAgent importPackage vs. managed bean in none scope - xpages

What is your prefered way to run application (business) logic in an XAgent?
XAgent using importPackage:
XAgent
importPackage(com.test.model.configuration);
FolderConfiguration.updateFolders(
facesContext.getExternalContext().getRequest().getReader());
XAgent using a managed bean in none scope:
faces-config.xml
<managed-bean>
<managed-bean-name>folderConfig</managed-bean-name>
<managed-bean-class>com.test.model.configuration.FolderConfiguration
</managed-bean-class>
<managed-bean-scope>none</managed-bean-scope>
</managed-bean
XAgent
folderConfig.updateFolders(
facesContext.getExternalContext().getRequest().getReader());
I am not sure about the pros and cons of both of them.
Thanks for any hints.

Both versions won't be significant different at run time performance.
So, it's more a matter of code design.
Managed bean's pros:
Java class reference is defined at a central place.
If you change Java package later you have to change the managed bean
definition only
JavaScript code is shorter
importPackage's pros:
use of Java class is independent from outside managed bean settings
Java class doesn't need to be instantiated if static methods only are called
I'd go for managed bean version if you use this Java class on several XPages or custom controls. Otherwise I'd use the importPackage or the direct call
com.test.model.configuration.FolderConfiguration.updateFolders(...)

Related

Utility methods in application scoped bean

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.

Inject ConversationScoped beans within an asynchronous method

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

java.io.NotSerializableException: org.primefaces.model.DefaultStreamedContent

I have a simple jsf 2.1 that used to work fine on Java EE 6 using primefaces 3.4.
When I migrated to glassfish 4.0 and primefaces 5.1 I've got the following exceptions each time I redeploy the project on Netbeans:
java.io.NotSerializableException: org.primefaces.model.DefaultStreamedContent
java.io.NotSerializableException: org.primefaces.component.datatable.DataTable
Even if this exception is thrown, the project is deployed and run correctly!
What could be wrong?
You've declared those types as a property of a view or session scoped managed bean. You should absolutely not do that. You should declare them as a property of a request scoped bean.
View and session scoped beans must be Serializable because view scoped beans are reused/shared across multiple requests on the same view in the same session, and session scoped beans are reused/shared across multiple requests in the same session. Anything tied to a specific HTTP session must be Serializable, because it enables the server to store sessions on disk, so it could be shared among other servers in a cluster, or survive server restarts.
The DefaultStreamedContent (and the InputStream it is wrapping, if any) may absolutely not be created and assigned as a view/session scoped bean property, not only because it's not serializable, but also because it can be read only once. You need to create this in the getter method only. This is indeed a rather special case which is fleshed out further in this answer: Display dynamic image from database with p:graphicImage and StreamedContent
The DataTable is a JSF component which you most likely referenced via binding attribute. It may absolutely not be assigned as a view/session scoped bean property, because UI components are inherently request scoped. Reusing the same UI component instance across multiple restored views in the same session may cause its state being shared across multiple requests (NOT threadsafe thus!) and/or potential "Duplicate Component ID" errors. See also a.o. How does the 'binding' attribute work in JSF? When and how should it be used?
NotSerializableException is thrown when an instance of a class must implement the Serializable interface.
If the class that throws the exception does not belong to a third-party library, find the class and make it implement the serializable interface.
If you do not want to serialize the objects in the class, you can mark the objects as transient, to make the serializable runtime ignore the objects.
You can read about it here

Difference between managed bean and backing bean

I came across the terms "managed bean" and "backing bean" in several forums. Many people think both are the same. But, there seems to be a slight difference. Can any one help me to understand the exact difference between these two terms?
Changing my initial answer - there is no meaningful difference between the two. The tutorial says that backing beans are later declared as managed beans. So, to summarize:
a backing bean is the class out of context
a managed bean is the backing bean whenever it is declared to be used with the JSF managed bean facility.
I've never actually used the term "backing bean", because I found no use to it. So you might be better off using only "managed bean". Note that in JSF 2.0 (and in CDI) you have #ManagedBean- so your bean is a managed bean.
BalusC suggested that "backing bean" is the definition, and "managed bean" is the instance. While this might have been the original idea of JSF creators, I don't think it is worth supporting it. CDI and spring for example don't have different term for "bean definition" and "bean instance".
The JSF 2.0 specification mentions the term "backing bean" only a few times, with no definition whatsoever. In addition to that it mentions "backing bean class", which might mean that "backing bean" != "backing bean class", which brings further confusion.
So to conclude - for me both are interchangeable, and I'd stick to only using "managed bean"
What is Managed Bean?
JavaBean objects managed by a JSF implementation are called managed beans.
A managed bean describes how a bean is created and managed.
It has nothing to do with the bean's functionalities.
What is Backing Bean?
Backing beans are JavaBeans components associated with UI components used in a page.
Backing-bean management separates the definition of UI component objects from objects that perform application-specific processing and hold data.
The backing bean defines properties and handling-logics associated with the UI components used on the page.
Each backing-bean property is bound to either a component instance or its value.
Backing bean also defines a set of methods that perform functions for the component, such as validating the component's data, handling events that the component fires and performing processing associated with navigation when the component activates.
What are the differences between a Backing Bean and Managed Bean?
Backing Beans are merely a convention, a subtype of JSF Managed Beans which have a very particular purpose. There is nothing special in a Backing Bean that makes it different from any other managed bean apart from its usage.
MB : Managed Bean ; BB : Backing Bean
1) BB: A backing bean is any bean that is referenced by a form.
MB: A managed bean is a backing bean that has been registered with JSF (in faces-config.xml) and it automatically created (and optionally initialized) by JSF when it is needed.
The advantage of managed beans is that the JSF framework will automatically create these beans, optionally initialize them with parameters you specify in faces-config.xml.
2) BB: Backing Beans should be defined only in the request scope
MB: The managed beans that are created by JSF can be stored within the request, session, or application scopes .
Backing Beans should be defined in the request scope, exist in a one-to-one relationship with a particular page and hold all of the page specific event handling code.
In a real-world scenario, several pages may need to share the same backing bean behind the scenes.
A backing bean not only contains view data, but also behavior related to that data.
Backing Bean is any bean that is bound with JSF UI. while Managed bean is any bean
Simply put,
You as developer do:
#ManagedBean(name="managedBean")
#RequestScoped
public class BackingBean {
// ...
}
JSF as bean management framework does under the covers:
BackingBean managedBean = new BackingBean();
externalContext.getRequestMap().put("managedBean", managedBean);
So, the backing bean is the concrete class which is developed by you and usually tied to the view, and the managed bean is the concrete instance, which is under the covers created and put in the desired scope by the bean management framework on demand, and available by #{managedBean} in EL. You never need to create and put it in the scope yourself. If you did so then there's no means of a framework-managed bean.
CDI #Named and Spring #Component do essentially the same thing as JSF #ManagedBean.
To learn more about how bean management frameworks like JSF, CDI and Spring find and create their managed beans, the following troubleshooter should provide in depth insight: Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable.
See also:
What components are MVC in JSF MVC framework?
JSF Controller, Service and DAO
JSF managed bean naming conventions
http://docs.oracle.com/javaee/5/tutorial/doc/bnaqm.html says
A typical JavaServer Faces application includes one or more backing beans, each of which is a JavaServer Faces managed bean that is associated with the UI components used in a particular page. Managed beans are JavaBeans components (see JavaBeans Components) that you can configure using the managed bean facility, which is described in Configuring Beans. This section introduces the basic concepts on creating, configuring, and using backing beans in an application.
http://docs.oracle.com/javaee/6/tutorial/doc/bnaqm.html makes no mention of "backing bean".
Managed Beans are managed (instantiated and destroyed) by container.
Backing Beans are managed beans that back views as data models.
I would say that the backing bean is a bean used strictly for UI purposes, that is, referenced in the jsp files. After all, all beans managed by JSF container are managed beans, however there are different contexts in which they might be used. For more see accepted answer here: JSF : ManagedBean, Good place to deal with Business Logic?
Backing Bean is a kind of Managed Bean. Managed Bean is an Object (i.e. instance of a Class ), created by a container (that's why it is called managed) and of course that Object has a Class and if you feel like it, you can create as many instances of that class no matter what annotation they have with m = new MyManagedBean(), just it will be a Not-So-Managed-Bean or at least not managed by a container but managed by you :)
And backing bean is a kind of managed bean (as Santosh put it: a convention) that usually uses the JSF requestScope (but in some frameworks like ADF there is even a designated scope only for backing beans called backingBeanScope - you would have never guessed) .
And yes... The flavor of jsf managed beans that one would call BackingBeans is used to bind UIComponents and write ActionListeners, while lets say "model beans" flavor would go in the session scope for example and hold your data
I took a very good (expensive) course on JSF. What I learned there is just about what is explained in http://www.avromroyfaderman.com/2008/07/from-backing-bean-to-managed-bean/.
Perhaps this difference is not the theoretical difference or the etymology of the terms, but it is certainly a very practical way to set up your architecture, especially if you are part of a large project with multiple developers and/or need to maintain a lot of code for a long time. Basically the idea is that you put your UI Business Logic in Managed Beans. Backing beans are sparse and just support the page itself.
From this link JSF - Managed Beans
Managed Bean :
Managed Bean is a regular Java Bean class registered with JSF. In other words, Managed Beans is a java bean managed by JSF framework.
From this link Creating and Using a Backing Bean for a Web Page :
Backing Bean :
In JSF, backing beans are JavaBeans used mainly to provide UI logic and to manage data between the web tier and the business tier of the application (similar to a data transfer object). Typically you have one backing bean per JSF page. The backing bean contains the logic and properties for the UI components used on the page.
NB:
For a backing bean to be available when the application starts, you
register it as a managed bean with a name and scope
Managed Bean:
A managed bean is a backing bean that has been registered with JSF (in faces-config.xml) or using Annotations. Managed Bean automatically created (and optionally initialized) by JSF when it is needed.
If you use Managed Bean in your application you have to use following syntax in JSF page to set or get values form bean
<h:inputText value="#{user.name}"/>
Backing Bean:
A bean that contains some or all component objects of a web form. Such a bean is called a backing bean for the web form.
When you use a backing bean, you need to wire up the components on the
form to those on the bean. You use the binding attribute for this purpose
Example:
<h:inputText binding="#{myForm.myComponent}" .../>
Observe how we are getting or setting values to Backing bean.
Backing Beans should be defined in the request scope, exist in a one-to-one relationship with a particular page and hold all of the page specific event handling code
Hope it useful to someone.

Unnecessary Session Beans in Ajax Enabled JSF Frameworks

I've noticed that when using Ajax heavy JSF 1.2 implementations like Richfaces you're somehow forced to declare more managed beans than you'll want as Session scoped so that state can be maintained across multiple Ajax requests; there are components that will just stop working.
For instance, I developed this application lately in which I had to declare almost all my JSF Backing Beans as Session Scoped in order to have component "x" working. Is there a way out of this, do you consider it a bad practice, or is just the price to pay for having Ajax enabled component in JSF 1.2.
Thanks in advance.
Session scope beans increase memory usage.
Another available scope is View Scope - This allows to keep a state of a bean between requests, while the user is still on the same view.
If you are using JSF2, please consider using #ViewScope above the bean name:
#ViewScope
public class myBean{
..
}
If you use RichFaces and JSF1.2, consider using <a4j:keepAlive /> under <f:view> in the view. for example:
<a4j:keepAlive beanName = "#{myBean}"/>
Read more info here
Another option is to use Seam conversation. Also, I wouldn't say components stop working, they still work.. it's your logic that needs to maintain some sort of state on the server.

Resources