#startup annotation for converter - jsf

In a JSF application I need to format an Integer in a customized way. I created a converter and following what I did in another project I annotated it with #Named and #Startup. I then linked that converter inside a h:outputtext.
The Integer was not formatted at all, probably because the converter had not been instantiated. Finally I replaced #Startup with #ApplicationScope and got the expected behavior.
As stated above I copied #Startup from a working application, so cannot understand the misfunctioning in the second application. What am I missing ?

Related

Using public field, will it mess with the proxies?

I'm wondering if changing the EL resolver so a bean can use public fields in jsf could cause issues with the proxies? [That's why it isn't a duplicate.] Aall managed bean fields have to be private in the framework, because that's how the EL resolver does things. However it's a bit cumbersome and looks useless most of the time.
#Named
#RequestScoped
public class myBean{
public int age;
}
So would it cause issue with proxies trying to intercept things or whatnot?
This guy in this question apparently changed the el resolver so it's doable
Unfortunately yes, it will mess with CDI.
Why? Because public field access is impossible when bean is proxied. With Weld during startup you will get a definition error:
WELD-000075: Normal scoped managed bean implementation class has a public field ...
It's going to work fine only for non-proxied scopes (#Singleton and #Dependant).
I agree it's a bit cumbersome and looks useless sometimes, so you have two solutions:
Use IDE to generate them automatically.
Use lombok project.
But none of them is perfect.

When to name a converter in JSF

I've been working with converters in my PrimeFaces SelectOneMenu objects. They work fine if I only tell which class the converter is referring to:
#FacesConverter(forClass = DescriptorVO.class)
public class DescriptorVOConverter implements Converter { ... }
This way, I don't have to explicitly tell the JSF component which converter should be used when it is populated with objects of class DescriptorVO.
However, I made a page that used a p:SelectManyCheckbox and I couldn't for the life of me know why it wasn't calling my converter. Then I gave it a name, like so:
#FacesConverter(forClass = RoleVO.class, value = "roleVOConverter")
public class RoleVOConverter implements Converter { ... }
and passed it as one of the component's properties
<p:selectManyCheckbox id="cbx_roles" required="true" converter="roleVOConverter"
requiredMessage="At least one role must be selected."
value="#{userView.selectedRoles}" layout="responsive">
<f:selectItems value="#{userView.roles}" var="role"
itemLabel="#{role.title}" itemValue="#{role}" />
</p:selectManyCheckbox>
and voi la, it started calling the converter correctly. This raised a question to me regarding when I should name my converters (through the value attribute) and when telling them which class the converter should be used with (with the forClass attribute) is enough. I never had to namy any converters when working with PrimeFaces, only for this particular SelectManyCheckbox component. Do different components have different necessities regarding converters or did I just get the concept of converters wrong?
That can happen when the value of the UISelectMany component references a generic java.util.Collection type like List<Role> instead of an array like Role[]. This is specified in javadoc of UISelectMany (emphasis mine):
Obtain the Converter using the following algorithm:
If the component has an attached Converter, use it.
If not, look for a ValueExpression for value (if any). The ValueExpression must point to something that is:
An array of primitives (such as int[]). Look up the registered by-class Converter for this primitive type.
An array of objects (such as Integer[] or String[]). Look up the registered by-class Converter for the underlying element type.
A java.util.Collection. Do not convert the values.
If for any reason a Converter cannot be found, assume the type to be a String array.
The reason is, the generic type <Role> is lost during runtime and not directly determinable. It works when you're using MyFaces instead of Mojarra as it will in case of a java.util.Collection inspect the actual type by manually iterating over <f:selectItem(s)> and determine the Converter based on first non-null value.
I created spec issue 1422 on this to get this in JSF spec and improve Mojarra too.
See also:
UISelectMany on a List<T> causes java.lang.ClassCastException: java.lang.String cannot be cast to T
Why does JSF put String values in a Map<..., Integer>? And how to work around it?
Use enum in h:selectManyCheckbox

need clarification on JSF and managed beans

i have some behavior im unable to understand,
so i started to recently learn JSF, im using TOMCAT 6, now i created JSF file , and i created two Managed Beans under different packages, but each bean have the same name.
1. First bean is com.app.TestBean.
2. Second bean is jsftest.TestBean.
now when i call my JSF page, i get to invoke the first bean, if i restart the TOMCAT , i get the result of the second bean, can any body explain what im doing wrong here ?
Unless you specified their name explicitely, the beans have their name/id assigned based on they class name.
So TestBean would be: testBean
So if you have conflicting class names, you need to explicitely specify their (different) name.
For example if you are using the annotation (which i suspect is the case), you need to do
package com.app;
#ManagedBean("testBean1")
public class TestBean {
...
}
and the other bean
package jsftest;
#ManagedBean("testBean2")
public class TestBean {
...
}
And then use either #{testBean1} or #{testBean2}

Netbeans warning: no enabled eligible for injection beans are found

I have two beans. First bean languageOfSystem:
#Named(value = "languageOfSystem")
#SessionScoped
public class LanguageOfSystem implements Serializable {
#Inject private JsfUtils eeJsfUtils;
and the second bean, userBb:
#Named(value = "userBb")
#SessionScoped
public class UserBb implements Serializable, LangUpdInterface {
#EJB
private EjbUtils ejbUtils;
#EJB
private PuserFacade puserFacade;
#Inject
private Direction direction;
#Inject
private PortfelDao portfelDao;
#Inject
private LanguageOfSystem languageOfSystem;
I inject languageOfSystem into userBb, and NetBeans IDE gives me warning in line with that injection:
no enabled eligible for injection beans are found
But I'm able to call methods from languageOfSystem in userBb and it works fine. So is this warning important and should I change smth?
And the second question. I use in this case observer design pattern, where userBb is dependent and languageOfSystem is the subject which has a list of dependents. I register userBb in subject list by calling appropriate method from languageOfSystem. Is it right when it comes to the two session beans?
But I'm able to call methods from languageOfSystem in userBb and it
works fine.
Your code does not look wrong - and it works. So this seems to be a Netbeans issues.
And the second question. I use in this case observer design pattern,
where userBb is dependent and languageOfSystem is the subject which
has a list of dependents. I register userBb in subject list by calling
appropriate method from languageOfSystem. Is it right when it comes to
the two session beans?
Are you aware that the CDI spec includes a powerful and typesafe implementation of the observer pattern? You definitely should check this out.
And two more things to mention here:
#Named(value = "languageOfSystem")
#Named(value = "userBb")
The value you are providing is already default. So you can leave it
out and simply write #Named instead.
Regarding the code you are posting: #Named is not required at all -
all it does is providing an EL name for use in JSF. Your code will
work just as good if you skip #Named altogether...
As to your first question:
This is a known netbeans bug (see here and here). However, the discussion in the first link indicates that it is rather an issue of the weld implementation and Netbeans' warning is according to the specification.
Nevertheless the bugzilla file says it will be fixed in Netbeans v7.2.
Until then you can still disable the warning (Tools --> Options --> Editor --> Hints)

What is the correct way to bind input value to JSF managed bean property?

I am new to JSF and managed beans. I have a managed bean with some private property with public setter and Getter methods. Now when I add the managed bean's properties to JSF forms, should I add the private methods directly or should I use call the property by Getter methods?
For example:
<h:inputText value="#{BeanName.userName}"/>
<h:inputText value="#{BeanName.getUserName()}"/>
Which one is correct in above?
Assuming that you're using JBoss EL or EL 2.2+, both ways would work fine in the initial display. But the first one is actually more correct because the second one would only get the value, but never set the value. If you want to collect input values, you should always go for the first way. The EL (Expression Language) will then automatically locate the getUserName() and setUserName() methods whenever needed.
The second way will never work when you're using standard JSF EL implementation since it doesn't support direct method calls.
To learn more about JSF, start at our JSF wiki page.
If in your java class you have something like
....
private String coolStuff;
public String getCoolStuff() {
return coolStuff;
}
....
Then in your jsf page you access it like so:
#{myBackingBean.coolStuff}
The framework automatically looks for a method called getCoolStuff()
Hope that helps
number 1 is correct from above it is the private field that you connect if you are using EL with JSF in your form.
You still need the getter and the setter which the managed bean calls to get the values so you can save them in a database ....etc

Resources