How to use resolveWidgetVar before PrimeFaces 8? - primefaces

https://github.com/primefaces-extensions/primefaces-extensions/blob/master/core/src/main/java/org/primefaces/extensions/renderer/CommandButtonSingleClickRenderer.java
This appears to be an elegant solution to disable and enable PrimeFaces CommandButton and available in version 8 and up of PrimeFaces.
Unfortunately, I'm unable to compile it in PrimeFaces 6.1, Java 8.
It now compiles with the suggested update, Thanks, but the method doesn't return the correct type - String.
It could be related to the structure of our DOM, we have multiple layers of xhtml, the first loaded index.xhtml doesn't have any buttons. But the CommandButtonSingleClickRenderer.java is being called. The properties of the CommandButton are all default values.
protected String getAttributeValue(final FacesContext context, final CommandButton button, final String attribute)
returns null
Added a check for null prior to the call to getToggleJS to get the pages with buttons loaded.
What is required in the commandButton ?
How do you call the CommandButtonSingleClickRenderer from xhtml ?

In PrimeFaces 8, the default String resolveWidgetVar(FacesContext context) method was introduced in the Widget interface.
Before that, so in PrimeFaces 6.1, you should use button.resolveWidgetVar().
See also the source of CommandButtonRenderer in PrimeFaces 6.1.

Related

What should be done to get around or resolve the PrimeFaces exception requiring the definition of a lazy attribute or one that doesn't result in null?

I am in the progress of upgrading a legacy application from PrimeFaces 6.2 to 11.0.0 (which is the newest available with maven - https://mvnrepository.com/artifact/org.primefaces/primefaces). I have had to make a number of changes, including adding Object as the parameter for RowEditEvent and TreeNode objects (which are now generic) and changing instantiations of DefaultStreamedContent to use .builder(). Now, I am facing the following error whenever I try to run the application and navigate to certain pages:
"javax.faces.FacesException: Unable to automatically determine the lazy attribute. Either define the lazy attribute on the component or make sure the value attribute doesn't resolve to null."
It looks like an exception is being thrown rather than a warning as is noted in the conversation here: https://github.com/primefaces/primefaces/issues/8436. It also looks like it was fixed, but for version 12 (which is not on the maven central repository).
I am wondering what my options are, or what could be done about this. Should I go back to an older version?
As a workaround you could create an application factory which sets the lazy attribute to false.
See: https://primefaces.github.io/primefaces/11_0_0/#/core/globalattributes
Is it a lazy DataTable which uses LazyDataModel? If yes, just set lazy=true, otherwhise set lazy=false

Primefaces calling a javax.faces 2.2 method but 2.1 is in the path in Websphere 9

I have an application deployed in WAS 9 using custom jsf provider (set to DEFAULT in WAS). Jars are in a shared lib with an isolated class loader. Everything worked fine until we migrated from richfaces to primefaces. We use javax.faces 2.1.29 but for some reason primefaces seems to detect that we are using 2.2 and is making a call to a method that only exists in 2.2 (getPassThroughAttributes). Looking at the stack versions in play seem correct so I'm not sure why the 2.2 method call is being made. Anyone run into this?
> 3/19/19 17:19:07:671 CDT] 00000091 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause Faces Servlet: javax.servlet.ServletException: javax/faces/component/UIComponent.getPassThroughAttributes(Z)Ljava/util/Map; (loaded from file:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar by
com.ibm.ws.classloader.CompoundClassLoader#abecddd0[library:trunkLib]
Local ClassPath: /opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpclient-4.5.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpcore-4.4.4.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/commons-codec-1.11.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-api-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-locator-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-utils-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.annotation-api-1.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jaxrs-ri-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jersey-guava-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/validation-api-1.1.0.Final.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/classes:/opt/IBM/WebSphere/AppServer_2/trunkLib/javassist-3.23.1-GA.jar
Parent: com.ibm.ws.classloader.ProtectionClassLoader#a5c5ece8
and
> Caused by: java.lang.NoSuchMethodError: javax/faces/component/UIComponent.getPassThroughAttributes(Z)Ljava/util/Map; (loaded from file:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar by
com.ibm.ws.classloader.CompoundClassLoader#abecddd0[library:trunkLib]
Local ClassPath: /opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpclient-4.5.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpcore-4.4.4.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/commons-codec-1.11.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-api-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-locator-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-utils-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.annotation-api-1.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jaxrs-ri-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jersey-guava-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/validation-api-1.1.0.Final.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/classes:/opt/IBM/WebSphere/AppServer_2/trunkLib/javassist-3.23.1-GA.jar
Parent: com.ibm.ws.classloader.ProtectionClassLoader#a5c5ece8
Delegation Mode: PARENT_LAST) called from class org.primefaces.util.Jsf22Helper (loaded from file:/opt/IBM/WebSphere/AppServer_2/profiles/server1/installedApps/loggerheadNode03Cell/trunk80_war.ear/trunk80.war/WEB-INF/lib/primefaces-6.2.jar
It looks like PrimeFaces searches the classpath for JSF 2.2 classes - and unfortunately in this case PrimeFaces must be finding the those classes in the WAS-provided JSF 2.2 bundle. Moving primefaces-6.2 out of your application trunk80.war and into the isolated shared library trunkLib should resolve this.
First lets begin that the PrimeFaces source is OPEN, it is easilly debugged. A simple search in the source (either locally in your IDE or in GitHub) will get you the source of Jsf22Helper.java. You can than inspect where this is being called. Running in debug mode is the easiest, but a search in the PrimeFaces repository in GitHub shows just one location in CoreRenderer.java
protected void renderDynamicPassThruAttributes(FacesContext context, UIComponent component) throws IOException {
if (PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()) {
Jsf22Helper.renderPassThroughAttributes(context, component);
}
}
Next you should inspect the
PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()
And the getter for this returns a property that gets its boolean value from
atLeastJsf22 = LangUtils.tryToLoadClassForName("javax.faces.flow.Flow") != null;
In here you see that for determining the 'minimal' version, they try loading a class that is only present in JSF 2.2 or up. This means that no matter whether you use parent first classloading or not or independent of where you put PrimeFaces, if javax.faces.flow.Flow is on the classpath, PrimeFaces will think JSF 2.2 is available. It does not matter if JSF 2.1 is also on the classpath and even before JSF 2.2 since this specific class is not present in JSF2.1 and will always be loaded from the JSF 2.2 jars.
To fix this you have three options
Override the PrimeFaces PrimeEnvironment.java (e.g. via reading an explicit context property from the web.xml so you can optionally manually override the version detection and create a pull request for this with PrimeFaces so they can accept it as an improvement
'Correct' the way to override the JSF version similar to How to make websphere 8.5 use mojarra not myfaces
Switch to JSF 2.2
The latter would be the best and might even just be working out of the box.

Primefaces DataTable filtering warning

I'm using primefaces 3.5, and i have a DataTable component in my form.
When i try to use filters like this primefaces showcase, I'm getting this warning message:
WARNING: DataTable j_idt7:j_idt8:someList has filtering enabled but no filteredValue model reference is defined, for backward compatibility falling back to page viewstate method to keep filteredValue. It is highly suggested to use filtering with a filteredValue model reference as viewstate method is deprecated and will be removed in future.
Can anyone help?
From here :
See the user guide on page 133 'Data Filtering' in the chapter
dataTable. There is a new attribute filteredValue that should point to
a List in a ViewScoped managed bean to store the filtered values the
user typed in.

RazorEngine extension method fails with RuntimeBinderException after upgrade to Razor 2/ RE 3.2

I have a RazorEngine project that fails following an upgrade to Razor 2.0 and RazorEngine 3.2.0
This worked fine in the previous Razor 1.0 based version of RazorEngine (3.0.8).
I have an instance (myInstance) of a class (MyClass) and and extension method:
namespace MyCompany.Extensions
{
public static class MyClassExtensions
{
public static string ExtensionMethod(this MyClass thing)
{
// do stuff
}
}
}
I want to call this in a RazorEngine view (simplified example, there are loads of these methods, and all fail the same way):
#using MyCompany.Extensions
#using MyCompany
#{
var myInstance = new MyClass(Model, ...);
}
Some text #myInstance.ExtensionMethod() some more text
This is in a text file that's compiled by RazorEngine:
string parsedResult = RE::Razor.Parse(fileContent, myModel, "testfile.txt");
The problem is that this line (which used to work) throws a RuntimeBinderException:
'MyCompany.MyClass' does not contain a definition for 'ExtensionMethod'
Note that if I change the text file to:
Some text #MyClassExtensions.ExtensionMethod(myInstance) some more text
It works fine, so I think it must find the extension method's namespace.
My first thought was that it must be considering the passed model as a dynamic (and hence anything derived from it as dynamic too), but it knows the expected type in the RuntimeBinderException. As the exception is run-time I think it must be failing to identify the extension method while the template is compiled, but why would that have changed?
I'm not sure what's changed between 3.0.8 and 3.2.0, or why this is broken. Is there something I need to add so that the extension method can be found while the template is compiled?
This is a bug in RazorEngine: the Razor.Compile works on TemplateBase<dynamic> (so Model and everything derived from it is dynamic too) and that means that no extension methods undergo the 'compiler-magic' to convert them to the static calls. Then Razor.Run passes the Model as the correct type, but the extension method syntax is called as an instance method.
There will probably be a fix for this soon (the bug's only a few days old and this is a corner case), but in the meantime I have a workaround: explicitly type the Model in the Razor template
#using MyCompany.Extensions
#using MyCompany
#{
ExpectedModelClass strongTypeModel = Model as ExpectedModelClass;
MyClass myInstance = new MyClass(strongTypeModel , ...);
}
Some text #myInstance.ExtensionMethod() some more text
This now works, because even though Model is still dynamic at compile-time that doesn't spread to myInstance any more.
It's not ideal, and everywhere I used Model now has to be strongTypeModel, but that's a much simpler substitution.

NetBeans - JComboBox warning - missing type arguments for generic class JComboBox<E>

I am using NetBeans IDE 7.1.2. When I compile my application I get the following warning:
warning: [rawtypes] found raw type: JComboBox
city = new javax.swing.JComboBox(); missing type arguments for generic class JComboBox where E is a type-variable:
E extends Object declared in class JComboBox
So, I guess I have to declare the JComboBox as:
JComboBox<String> city = new JComboBox<String>();
But how do I do this in NetBeans, using the Matisse (Swing GUI Builder)? Please help.
In Netbeans 7.2 you can click on Code section for JComboBox, and then write type into "Type Parameters", in your case: <String>.
Java 7 introduced generics to the JComboBox. One solution to your problem would be to ust Java 6.
I'd bet the latest version of Netbeans (7.2) will have a solution for this (although I'm not positive).
Otherwise, if I remember right, you can view the code generated by Netbeans. If so, you may be able to add the generic arguement yourself. It's been many months since I tinkered with Netbeans though...
Also, if the Netbeans allows you to, you can add the #SupressesWarnings annotation above the JComboBox declaration (or even above the class declaration, although that changes it's scope). It would be something like this:
#SuppressWarnings("rawtypes")
JComboBox city = new JComboBox();
There are lots of options, but Netbeans may hold you back from implementing some of them.