Richfaces: NoSuchFieldElementException AjaxChildrenRenderer for HTML Tag - jsf

I use richfaces 3.3.3.Final with Seam and facelet.
I have plugged a profiler on my application and I have a weird behavior.
When I log all exceptions thrown by the application, I have more than 10 000 NoSuchFieldElementException in 10 minutes.
After many search, I found the problem:
When I started an ajax request by a4j:support, the NoSuchFieldElementException is thrown by the AjaxChildrenRenderer in these lines (199-202):
String componentType = (String) component.getClass().getField("COMPONENT_TYPE").get(null);
result = _specialComponentTypes.contains(componentType);
The component variable is a UIInstructions and it has no "COMPONENT_TYPE" field. So, the exception is normal.
This exception is thrown for each html block contained in my page. For example:
<h2>Test</h2>
<span></span>
When I reRender a block with html tag, the exception is thrown.
I have very complex page, so I get many of this exceptions.
How I can do to avoid this exception ? May be a parser option to avoid to go in this class for html block.
Thanks for your help.

As a temporary solution, you could modify the source code to add an instanceof check which should skip that block and then ship the modified source code with your webapp. Ship it either as a single class with identical package/class name in web project itself (javadoc-document it properly), which would always have preference in classloading over the one in the JAR, or as a modified and rebuild JAR file.
if (!(component instanceof UIInstructions)) {
String componentType = (String) component.getClass().getField("COMPONENT_TYPE").get(null);
result = _specialComponentTypes.contains(componentType);
}
As a lasting solution, you should report it as a performance issue to the RichFaces guys so that they get it fixed and release a new update, but I don't think that they will prioritize 3.3.x updates that much. I.e. it might take longer than you'd expect.

Related

Why does JHipster page not accept String for ZonedDateTime

I recently changed my domain objects from LocalDate to ZonedDateTime. I also created a brand new play JHipster application and one play entity choosing ZonedDateTime for two class members. The test application (new) works while my existing application does not, even after going through all the code twice. I loaded CSV data using Liquibase and my listing code shows the dates properly. Here's what the data looks like in my Maven output, e.g. entrydate='2017-02-23T19:53:18-05:00[America/New_York]', transaction='Initial Balance',
When I choose to update the date-time value with the "datetime-picker" in the dialog.html, a string date time is shown in the text box but when I push "Save" I get an "Internal Server Error" and the Maven output shows:
.HttpMessageNotReadableException: Could not read document: Text '2017-02- 26T00:53:18.000Z' could not be parsed at index 23 (through reference chain: org.ciwise.blackhole.domain.GenLedger["entrydate"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Text '2017-02-26T00:53:18.000Z' could not be parsed at index 23 (through reference chain: org.ciwise.blackhole.domain.GenLedger["entrydate"])]
Does anyone have an idea why the picker would produce String text in the text box that isn't acceptable when the HTTP PUT occurs (edit)?
My application does use Service classes but they handle the same Java domain objects as the JPA Repository classes do.
One more thing, the schema for the API shows e.g. "entrydate": "2017-02-23T21:44:04.859Z", but the actual JSON return is "entrydate": "2017-02-23T19:53:18.000-0500",
I'm hoping someone else has encountered this before.
Thanks
David
The answer here was to re-introduce application.yml. Inside this file it defines some Spring profiles but of most importance, it provides an option for Jackson serialization into JSON e.g.
jackson:
serialization.write_dates_as_timestamps: false
This resolved my issue.

Double call to action - prettyfaces - jsf

I am making a page in which I call a PrettyFaces page-load action method:
<url-mapping id="informes-perfil">
<pattern value="/informes/#{informesPerfilMB.codigo}" />
<view-id value="/faces/informes_perfil.xhtml" />
<action onPostback="false">#{informesPerfilMB.load()}</action>
</url-mapping>
For some reason, the informesPerfilMB.load() action is called twice, and the parameter value in the second call is 'null' or 'RES_NOT_FOUND'.
Here is my load method:
public void load() {
if (isPostBack) {
isPostBack = false;
try {
System.out.println(codigo);
informe = informeEJBServiceLocal.getByCodigo(codigo);
this.buscarInformeIngreso();
this.buscarInformeOtroIngreso();
} catch (EJBServiceException e) {
e.printStackTrace();
}
}
}
The isPostBack variable is initialized to false, so this should prevent the method from being called again, but for some reason it is.
This code first prints String: dcc509a6f75849b.
Then when the load is repeated, it prints this: RES_NOT_FOUND
I hope this code helps explain what is happening enough to solve my problem, Thanks.
I've seen this happen on my similar system in the past. I think it's an interaction between faces and prettyfaces with missing files. The RES_NOT_FOUND part comes from the network traffic. There's some likely faces resource (or stylesheet) that it's trying to find in libraries and when it can't, it essentially causes the browser to go to the URL /informes/RES_NOT_FOUND. For some reason, it would often find that resource if I refreshed the page and wouldn't issue a RES_NOT_FOUND URL.
First, I'd open up the page source, and you'll find RES_NOT_FOUND, likely along with the stylesheets. Given the position of it, you might be able to correlate it to the resources loaded in your xhtml files and see which one's missing. If that doesn't help, try the developer tools and see which resources are loaded and which are not. Then make sure the resource is present, deployed, and is in the correct location.
If it's not something that you can control (like a library resource), you can always make sure your setCodigo function ignores values of "RES_NOT_FOUND".
public void setCodigo(String value) {
if (!"RES_NOT_FOUND".equals(value)) {
this.codigo = value;
}
}
You may be able to modify your security or servlet-mapping settings (in WEB.XML) to prevent URLs ending in RES_NOT_FOUND from getting to the prettyfaces pages, but I don't know enough about it to do that.
First, the reason your isPostBack variable is called twice is most likely because you have two instances of the bean, not one singleton instance. There are a few reasons this could be happening:
Your bean is request scoped and multiple requests are being made to the page.
Your bean is being created multiple times by parts of your application that use it and call the load() method.
I also believe it is possible your method is being called twice because of the way you have written your EL expression (I'm not 100% sure):
<action onPostback="false">#{informesPerfilMB.load()}</action>
^^
Note the parenthesis at the end of your method expression. I believe this will force EL to evaluate the method when the expression is evaluated. Your method expression should look like this:
<action onPostback="false">#{informesPerfilMB.load}</action>
You should also check for other places in your application where this method might be called.
Please let me know if this helps.

What does omnifaces JNDI.lookup not have a checked exception for NamingException?

I replaced all of my JNDI lookups with JNDI.lookup() method because it seemed convenient, dealt with dynamic return types, etc. All was great...but now I just noticed that the checked exceptions that I had to catch before are no longer there.
I assumed this was because it would have just returned null if the JNDI variable didn't exist but it doesn't. It now just throws an unchecked exception.
Any idea why? Is there a way of just returning null for non-existant variables instead?
I created a bug for this on the omnifaces website: https://github.com/omnifaces/omnifaces/issues/141
Not sure if this is intended behavior or not.
Is there a way of just returning null for non-existant variables instead?
It does that for NameNotFoundException. The problem was here not in OmniFaces, but in the environment, which was GlassFish 4.1 in your specific case. It unexpectedly wrapped the NameNotFoundException in another NamingException, hereby causing the underlying NameNotFoundException to slip through and bypass the return null condition.
This has been fixed with help of Exceptions#is() utility method as per this comment. It will be available in OmniFaces 2.2.

Accessing methods from imported jars in managed beans

I'm sure I'm missing something, but I'm not seeing it at all.
I'm creating PDFs using iText, and I want to do this in a bean. I've created one, but it's been erroring out. It seems some of the ways I've usually worked in Java don't seem to work in this bean.
For example, this line:
com.itextpdf.text.Document document1 = new com.itextpdf.text.Document();
will throw the error java.lang.NoClassDefFoundError: com.itextpdf.text.Document, even though the jar is imported, in the build path and com.itextpdf.text.Document is imported in the bean.
if you change it to this:
com.itextpdf.text.Document document1;
or
com.itextpdf.text.Document document1 = null;
the error goes away. I don't understand why one way works and the other doesn't, but it's a fairly easy change to make.
Now I need to set the page size. This will work in Eclipse:
document1.setPageSize(PageSize.LETTER);
but this is the error I get:
java.lang.NoClassDefFoundError: com.itextpdf.text.PageSize
Which might be because I've set it to null to initialize it. But
document1 = new Document();
and
document1 = new com.itextpdf.text.Document();
both throw java.lang.NoClassDefFoundError: com.itextpdf.text.Document
Oddly, the import statement for (iText) Document warns me it is never used.
document1.open();
will give the error java.lang.NoClassDefFoundError: com.itextpdf.text.Document as well.
So, am I missing something in the syntax in beans? I've created Notes Java agents, XAgents, and straight up Java Eclipse projects that work, but I can't get the methods to work in a 8.5.3 Java Bean. I imported the iText jars into WebContent\WEB-INF\lib and then added those (via add jars, not add external jars) to the build path. I've gotten the latest jars and I'm using them, I've built and cleaned, the bean is in faces-config. But I'm doing something wrong, and I can't see it.
If someone could point me in the right direction, I would be very grateful.
Cheers,
Brian
EDIT:
The license isn't a problem, but I still can't get the class to load even using the classLoader:
Thread currentThread = Thread.currentThread();
ClassLoader clCurrent = currentThread.getContextClassLoader();
//ClassLoader clCurrent=com.ibm.domino.xsp.module.nsf.NotesContext.getCurrent().getModule().getModuleClassLoader();
try {
currentThread.setContextClassLoader(Activator.class.getClassLoader());
DebugToolbar.get().info("after setting up FileOutputStream");
com.itextpdf.text.Document document1 = new com.itextpdf.text.Document();
//com.itextpdf.text.Document document1;
//com.itextpdf.text.Document document1 = null;
//document1 = new com.itextpdf.text.Document();
//document1.open();
document1.setPageSize(PageSize.LETTER);
I still get java.lang.NoClassDefFoundError: com.itextpdf.text.Document
I've cut the beans out, cleaned, built, pasted back in, cleaned built, still the error.
I appreciate the assistance.
Brian
Most likely you have a classloader isssue. Unless your app is strictly for internal use, you might reconsider use of iText since it is GPL. Apache PDFBox is an Apache licensed alternative (I'm particularly fond of) or Apache FOP (I'll complete the ]2 missing articles](http://www.wissel.net/blog/htdocs/DominoXSLT), promise). Of course OpenNTF's POI4XPages might just be what you need.
I called Lotus/ICS support. It seems for 8.5.3, if you put the jars in ~Lotus\Notes\jvm\lib\ext they will load. I'm testing this on my local, but the same path should work on the server. I'll test that Monday. I had researched, and if that is mentioned I didn't find it. Jars will be a design element in 9, putting them in a directory like this should not be needed for that version, but it seems that adding them this way is more consistent now. The jars have loaded properly for some applications I've made, so this confused me a bit.
Stephan and Panu, thank you for responding.
Brian

trust set to Full, but web part still causes SecurityException

I've got a web part that accesses the SP object model, packaged in an assembly which is signed and deployed to the GAC. The web.config is set for "Full" trust, and yet my web part throws a SecurityException. The offending lines of code:
SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(() =>
{
foreach (SPGroup g in user.Groups)
{
identity += String.Format(",'{0}'", g.Name.ToLowerInvariant().Replace(#"\", #"\\"));
}
}));
It appears that the exception is thrown when RunWithElevatedPrivileges is called (in other words, my delegate doesn't execute at all). Any ideas? I'm completely bewildered at this point.
update: here's what the code looked like before I wrapped it in the RunWithElevatedPrivileges method:
public MyWebPart()
{
context = new MyProject.Data.MyDataContext(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString);
SPUser user = SPContext.Current.Web.CurrentUser;
identity = String.Format("'{0}'", user.LoginName.ToLowerInvariant().Replace(#"\", #"\\"));
foreach (SPGroup g in user.Groups)
{
identity += String.Format(",'{0}'", g.Name.ToLowerInvariant().Replace(#"\", #"\\"));
}
identity = '[' + identity + ']';
}
And the exception:
System.Security.SecurityException occurred
Message="Request failed."
Source="Microsoft.SharePoint"
StackTrace:
at Microsoft.SharePoint.SPBaseCollection.System.Collections.IEnumerable.GetEnumerator()
at MyProject.MyWebPart..ctor()
InnerException:
Based on the highlight provided by the exception helper, it looks like the attempted access of the SPUser.Groups property is the problem: user.Groups.
What's got me really confused is that this exact code was working fine two days ago, but I had some other problems with the farm and basically had to rebuild it. After getting everything else back up again, I went and tried to add this web part to a page and this problem manifested itself. I tried wrapping the code in the RunWithElevatedPrivileges wrapper to see if I could isolate exactly the offending bit, but it looks like anything that touches the SP oject model causes the exception, including the RunWithElevatedPrivileges method.
update2: I still don't know the real reason this was failing, but it was happening when I was trying to add the web part. After setting breakpoints in the debugger, I realized that the constructor was being called twice; the first time, it all worked exactly as expected, but the second time was when the exception was being thrown. I still have no idea why. I found two ways around this: move the offending code out of the constructor into a later point in the lifecycle of the web part, or comment out the code to add the web part, then uncomment it and redeploy.
Apparently, the reason this "worked 3 days ago" was because I had added my web part to a page a long time ago, and then added the above code to the constructor. Since the web part was already added, I never saw any problems. Later, when I recently had to rebuild the site and add the web part to the page again, this problem manifested itself. So technically, it didn't "work" before, I just wasn't doing the thing that made it misbehave.
Anyway, like I said - I still don't know the true cause of the exception, so answers along those lines are still welcome.
The problem could occur if you try to work with SharePoint objects which were created outside of the RunWithElevatedPrivileges() method, and therefore still hold their old security context. In your case you use a SPUser object which was not created within the RunWithElevatedPrivileges() method.
To work around, you should create the object you want to work with within the delegate. Safe Ids or URLs outside of the delegate, to use them for recreating the objects. E.g.: safe the URL or ID of a SPSite object and use it to create it again within the delegate.
public void Demo()
{
string siteURL = SPContext.Current.Site.Url;
SPSecurity.RunWithElevatedPrivileges(delegate(){
using (SPSite safeSite = new SPSite(siteURL))
{
// place your code here ...
}
});
}
Perhaps you could post the stack trace so we can get some more information.

Resources