rich:autocomplete not working - jsf-2

We are upgrading from jsf 1.2 to jsf 2.
We are using apache myfaces 2.1 and rich faces 4.3.
Below is the xhtml code prior to migration :
<h:inputText id="#{userSearch}" value="#{bean.input}"/>
<rich:suggestionbox for="#{userSearch}" var="rslt" suggestionAction="#{bean.getSearchList}">
</rich:suggestionbox>
As per migration doc , replaced <rich:suggestionbox> with <rich:autocomplete>.
Following is the xhtml code :
<rich:autocomplete mode="ajax" autocompleteMethod="#{bean.getSearchList}" />
Below is the getSearchList method
public List<CustomObject> getSearchList(String searchNow) {
}
The <rich:autocomplete> component exists inside a custom component which is invoked like this :
<example:SearchUsr bean="#{someOtherObject.bean}"/>
The issue i am facing is , when an input is entered inside <rich:autocomplete> , ajax call happens but i am am getting below exception :
Target Unreachable, identifier 'bean' resolved to null.
I printed the value of bean (of bean.getSearchList ) inside xhtml and it is not null.
Am i missing anything while using <rich:autocomplete> ? Please help.
EDIT 1 :
When the autocompleteMethod is invoked like this : #{masterBean.object2.object3.getSearchList}, this issue is not observed where masterBean is the one defined in faces-config.xml with session scope. Also autocompleteMethod must accept String argument and not object.
So is it that we cannot invoke autocompleteMethod on an intermidiate object ? It has to be a bean defined in JSF ? It is strange , but I am observing the same behaviour.
EDIT 2 :
While trying to search for an answer , got this link which states the same issue : autocomplete method does not resolve bean if ui:included and only one parameter provided
It gives two options : define autocomplete method with 3 parameters , use a composite component, rather than a ui:inlcude.

As evident from EDIT 2 , the autocomplete method signature is changed as :
public List<CustomObject> getSearchList(FacesContext context, UIComponent uiComp,String searchNow) , and the issue is resolved.

Related

Appium page object model #AndroidBy is taking variable name instead of actual value

I am using #AndroidBy in page object class
#AndroidBy(accessibility = "Animation")
public WebElement animationButton;
When I run the test I get the following error.
org.openqa.selenium.NoSuchElementException: Can't locate an element by this strategy: By.id: animationButton;
Whats interesting here is that appium is looking with wrong locator strategy(id instead of accessibility) with variable name as value not the actual value given.
Same happens when I used xpath or other locator strategies.
but works fine if use driver.findElementByAccessibilityId("Animation").click();
I am unable to understand why this error is thrown.
Works fine when I use #FindBy with xpath but I cannot use accessibility id with it.
You should be using #AndroidFindBy instead of #AndroidBy
#AndroidFindBy(accessibility = "Animation")
public WebElement animationButton;

Debugging JSF ManagedProperty NullPointer

Using JSF 2 on JBoss AS 7
Getting the following error:
07:36:39,579 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-/172.20.91.126:12580-16)
Error Rendering View[/views/afgarendesok.xhtml]:
com.sun.faces.mgbean.ManagedBeanCreationException:
Unable to set property searchManager for managed bean afgArendeBacking
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:615)
The searchManager property is defined in the AfgArendeBacking class as:
#ManagedProperty(value="#{afgArendeSokManager}")
private AfgArendeSokManager searchManager;
#Override
public AfgArendeSokManager getSearchManager() {
return searchManager;
}
public void setSearchManager(AfgArendeSokManager searchManager) {
this.searchManager = searchManager;
}
The AfgArendeSokManager is a #ManagedBean that is #SessionScoped.
Two things I don't get. One is why the error shuts down all usage of JSF not just for the session producing the error. The error seems to appear after non-usage both below the default session timeout and beyond. The other odd this is that a null pointer exception at line 606 in the BakedBeanProperty has to be the one the writeMethod variable. That variable is created via the PropertyDescriptor.getWriteMethod() call. This should have bombed earlier when creating baked bean (i.e. bakeBeanProperty method).
Any ideas how to debug? The property "searchManager" is resolved correctly since we can use the JSF views normally (both the getter/setter exist).
The search manager is our session scratch pad for propagating stuff between view and request scoped backing beans.
The article explains the issue of using reflection to access methods with covariant return types (see here: https://dzone.com/articles/covariant-return-type-abyssal). The article relates to Java 6 but the background information is very useful.
The issue you're facing and that hit us just this week (using Java 1.7.0_40) is not one of EL but of the java.beans.Introspector.

JSF component object

There are many tutorials on the internet where component object on JSF page is used.
Usually component.clientId or component.valid are used.
Example
<h:inputText .... styleClass="#{component.valid ? '' : 'ui-input-invalid'}"/>
If i create page with such component, i get an error:
javax.el.PropertyNotFoundException:
The class 'javax.faces.component.UIPanel' does not have the property 'valid'.
I googled that for inputText should be there UIInput class (which has isValid method), but i have there UIPanel (which dasn't).
Any idea why is there UI Panel?
(Java EE 6, JSF 2.1, Weblogic 12.1.2)
Whether or not a single component is valid is irrelevant in the long run; the entire request will be marked as invalid, even if it's as a result of the failure of a single component.
You should be retrieving the status of a request on the facesContext implicit EL object
<h:inputText .... styleClass="#{facesContext.validationFailed ? '' : 'ui-input-invalid'}"/>
Nothing I've seen in the 2.1 or 2.2 API supports the the presence of a valid attribute for the component implicit EL object. It's an implementation of javax.faces.component.UIComponent
Reference:
UIComponent Javadoc

Calling Methods and Functions

in jsf2 if we have some function like
public String greeting(String gtr) {
return "Hello " + gtr;
}
then from jsf page we can call this function as
<h:outputLabel value="#{greetingBean.greeting['some-name']}"
now my question is i want to pass the dynamic parameter from the same bean class instead of 'some-name' something like value="#{greetingBean.greeting[greetingBean.name]} is it possible ?
i required this because i have value in Map<String, ArrayList> and want to edit particular ArrayList value ?
any suggestions ?
Brackets are used to replace the dot notation. That is,
#{greetingBean.greeting['some-name']}
is the same as
#{greetingBean.greeting.some-name}
So, the greeting method will not be called. Instead, JSF will try to access a greeting property, and then try to access a some-name property of the object returned by greeting property. That is, your code above is already generating an error.
If you are using EL 2.2 and want to call an action, simply put:
#{greetingBean.greeting('some-name')}
or
#{greetingBean.greetingThatReceivesAMap(greetingBean.name)}

Date conversion exception inside JSF composite component

When I access a JPA managed date value from JSF, it comes back with an javax.faces.component.UdateModelException saying
'Cannot convert 01.01.10 00:00 of type class java.util.Date to class org.apache.openjpa.util.java$util$Date$proxy
Using a JPA-managed date value (which means it is proxied) works fine when it is used directly from the EL likes this:
'<h:outputLabel value="MyDateValue" for="input"/>
'<h:inputText id="inputDate" value="#{bean.myDate}"/>
However, it causes trouble when trying to use it with composite components
and gives back the following converter exception and thus can't update the model...
The (simplified) JSF composite component inputDate.xhtml
<head>
<title>A date input field</title>
</head>
<composite:interface>
<composite:attribute name="dateValue"/>
</composite:interface>
<composite:implementation>
<h:outputLabel value="MyDateValue" for="input"/>
<h:inputText id="input" value="#{cc.attrs.dateValue}"/>
</composite:implementation>
Assumption:
It seems the proxy replacement in OpenJPA is handled differently when the value is being accessed from inside a composite. My guess is the EL-resolver handles calls to object values differently when it is passed to composites. Passing it to composites means it is first accessed within the composite, which is too late and the required replacement of the proxy is not accomplished (thus the converter exception)
So I tried to change the Expression Language for MyFaces, but it didn't work in Websphere, even though I changed the class loading to parent last and provided el-impl and el-api from glassfish in the lib folder and inserted the necessary context-param for MyFaces
How do you guys use JPA-managed dates (or other proxied entities) in composite components???
If you are using the sun EL implementation you might use the following ELResolver which works around this issue:
public class BugfixELResolver extends ELResolver {
//...
#Override
public Class<?> getType(ELContext anElContext, Object aBase, Object aProperty) {
if (aBase.getClass().getCanonicalName().equals("com.sun.faces.el.CompositeComponentAttributesELResolver.ExpressionEvalMap")){
Object tempProperty=((Map)aBase).get(aProperty);
if (tempProperty!=null&&tempProperty.getClass().getCanonicalName().equals("org.apache.openjpa.util.java.util.Date.proxy")) {
anElContext.setPropertyResolved(true);
return java.util.Date.class;
}
}
return null;
}
}
Add it to the faces-config this way:
<el-resolver>
xxx.BugfixELResolver
</el-resolver>
This workaround can also be used in environments where you can not change the EL implementation (like websphere etc.).
Here is the workaround. The problem seems to be WebSpheres' ExpressionLanguage Implementation or rather the order resolvers are executed. Registering the JBoss EL implementation works and resolves the date proxies before calling the composite component. I also tried the Glassfish EL, but it didn't work either...
Registering a alternative EL is quite strange: The setting in web.xml for MyFaces is
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Additionally under WebContent/META-INF/services/ a file named javax.el.expressionFactory is needed with this single line org.jboss.el.ExpressionFactoryImpl. The class comes from jboss-el-2.0.2.CR1.jar
(sorry, couldn't find the link to a maven repo)
I will keep you updated once I find a better solution...

Resources