JSF ui:debug causing NullPointerException - jsf-2

My JSF application has a <ui:debug> tag in the top level template. I have a data item creation page that saves the item to the DB. The DB then returns the saved item which I store in the JSF flash. I then redirect to a new page and display the item that I retrieved from the flash. When I view the page, the Debug page is shown with a NullPointerException and sometimes there is no stack trace and other times there is a stacktrace similar to (don't pay attention to the specific line numbers.
NullPointerException
at com.sun.facelets.util.DevTools.writeVariables(DevTools.java:158)
at com.sun.facelets.util.DevTools.writeVariables(DevTools.java:144)
at com.sun.facelets.util.DevTools.debugHtml(DevTools.java:135)
at com.sun.facelets.tag.ui.UIDebug.writeDebugOutput(UIDebug.java:92)
at com.sun.facelets.tag.ui.UIDebug.encodeBegin(UIDebug.java:81)
...
If I remove the <ui:debug> tag, then my page is successfully displayed. What is causing the NullPointerException?

Part of the job of the <ui:debug> tag is to display the contents of all the various JSF scopes including the "flash scope". DevTools.writeVariables is a helper function that is used to turn the objects in the scopes into something readable to display in the debug page. It uses methods like toString() to display the objects. The object that was stored in the flash, overrode the toString() method with the following boilerplate code
#Override
public String toString() {
//TODO: Supply implementation
return null
}
Since the toString() was returning null, it later caused a NullPointerException. If you properly implement toString(), this error will not occur.

Related

New entries in nested ViewModel are not recreated on ModelState.Merge()

We are using the well known Post-Redirect-Get pattern to prevent double posting in our MVC application. Like most implementations we store the Model-State inside TempData in the Http-Post-Action on errors and restore the Model-State with ModelState.Merge() inside the action we are redirected to. This works very well in most cases but breaks in the following case where we are adding new elements to a nested View-Model.
A editor template on the page is refreshed and contains an additional nested view-model element.
In another field on the surrounding view that incorporates the editor template another field is invalid and will prevent the commit into the db and forces the PRG into the error path (redirect to GET).
When the page gets submitted the Model-State contains the new nested element Property[n+1].Value and its value and is stored into TempData. After the Merge() the model-state in filterContext of the redirected to Get-Method contains the additional element.
Now when the view gets rendered the new element does not recreate because it is only in the model-state but not in the model. View creation loops over the model (that doesn't have the new nested object) and the EditorFor<> gets the value from the model-state which is as expected. Is there a generic solution to this problem?
Apparently there is no quick solution to the problem. We switched from a redirect on the error path in the controller (strict PRG) to a implementation described in this blog. It works very well and did even speed up the application as the returned json on the controllers error path is handled much faster than a full ViewResult.

Handling application exceptions and bean validations in JSF2 managed bean

I am building a JSF2 application with multi-lingual content.
1) Bean validation will be used for validating the form fields. I use ValidationMessages properties files to define locale specific error messages and use the <h:message> tag for displaying the correct error message on screen.
2) For application specific exceptions, I currently have a generic ApplicationException which is handled in managed bean methods. Inside the exception catch block, I set a "msg" field in the bean with a custom error message (For e.g: "The inventory cannot be updated as no matching product code found").
In the xhtml pages, I check if the "msg" string is not empty and display it on top of the page.
Is there a better way to handle display of success and error messages in JSF?
Can I simply throw the ApplicationException in managed beans and have a generic handler to handle the exceptions and display messages in the relevant view?
I read https://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception-jsf2, but I am not able to map it to my requirement
You're doing it almost properly. The way for the component validations is the one to go. However, for your managed bean logic, it's not necessary to implement a custom String property in your bean. Just add the message you want in your action method and it will be displayed by the h:messages tag:
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
"The inventory cannot be updated as no matching product code found","");
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, message);
Using an ExceptionHandler for just displaying a message seems overcomplicated. It also won't work for asynchronous (Ajax) requests, unless you use a third party solution like Omnifaces.
See also:
JSF 2 Global exception handling, navigation to error page not happening

Infragistics grid's GET returning empty response

I'm trying to use Infragistics' grid to display a list of items from my Database. I'm using code-first method with Entity Framework in an MVC application with Razor engine. Every thing is working fine in the view except the Infragistics grid.
Here is my home view:
#using Infragistics.Web.Mvc
#model IEnumerable<BusinessModel.Models.TestPlan>
#{
ViewBag.Title = "Home";
}
#( Html.Infragistics().Grid<BusinessModel.Models.TestPlan>(Model)
.AutoGenerateColumns(true)
.DataSourceUrl(Url.Action("igListTestPlan"))
.DataBind()
.Render())
Here is my controller:
[GridDataSourceAction]
public ActionResult igListTestPlan()
{
return View(service.getListTestPlan());
}
Using firebug I can clearly see that the request is sent with a status code "200 OK", but the response tab is empty. It also causes an error in the console (in infragistics.js):
Uncaught TypeError: Cannot read property 'length' of undefined
I guess it's because of the empty response.
What I tried:
Debugging my controller showed me that return View(service.getListTestPlan()); doesn't return an empty list: I have 3 valid items in.
I also tried Html.Infragistics().Grid<BusinessModel.Models.TestPlan>(Model__.ToList()) but nothing changed. Also Html.Infragistics().Grid(Model) tells me I've got invalid parameters
Thanks in advance.
I think I have a pretty good idea why you are getting this, happened to me as well.
The MVC wrappers provide defaults for the way the grid model handles data on the server (serializing the data source to an object with 'Records' of your data and supportive 'Metadata'). However, if you do that yourself since you don't define a key of your own you are stuck with a default key 'Records' that is used to filter the response and since it's not there..well you get 'undefined' data fed to the grid :)
So solutions:
1) Wrap your response and define matching key using the "ResponseDataKey" property of the grid. I am suggesting this because as far as I recall it's a good practice to wrap responses in a single object - think there were some security implications.
2) If you don't feel like doing this and just want to get it working now then set the "ResponseDataKey" to empty string ("" will do) so your response will be properly filtered(or rather not).
On the second part of binding the grid directly to model data in the view - you are correctly getting the error as far as I see. The DataSource property explicitly states the source must implement IQueryable instead of IEnumerable. Slap a .AsQueryable() in there and that should work fine as well.
Let me know if this helps :)

Confused about JSF Lifecycle

I want to show a page that renders a list of 'Group' entities, so my page (xhtml) has this in it
<f:event type="preRenderView" listener="#{groupController.loadGroups}" />
This is called when the page loads, and yesterday it was returning a list as expected. The method looks like this
public void loadGroups() {
allGroups = groupDao.findAll();
}
Now I added a form to save a new group (on the same page). When I save that form, it calls this method:
public String save() {
groupDao.create(group);
return "/admin/groups?faces-redirect=true";
}
I have confirmed that the group is saved in the database. But, I was expecting the "return" statement to reload the page as if entering it for the first time, calling the 'preRenderView' method etc etc.
When it comes back into the page it does call that method, but am using a datalist to display the collection of groups returned and when that makes a call to
public Collection<Group> getAllGroups() {
return allGroups;
}
... the 'allGroups' variable has been reset back to null.
I haven't touched JSF for a couple of months and I think I used to understand all this but I obviously don't. Could anyone give me a clue what I'm doing wrong?
If I find the answer (digging my books out right now) I will post an update. Thanks though.
Update: just to clarify, I thought the loadGroups method would be executed before the getAllGroups method, since it's a preRenderView event. But they seem to be getting executed the wrong way around (getAllGroups is called first, before loadGroups() has populated the collection). It's a ViewScoped bean by the way.
I'm not sure why my original version doesn't work, but if I get rid of the preRenderView statement in my page, and add a #PostConstruct annotation on the loadGroups method, it works fine. I understand why the #PostConstruct method would work, but not why the preRenderView doesn't work. Anyway, its working if I do that...

MVC Controller Called twice

I have a Product controller with Index action, which basically creates the view form for post and Index (Post action verb) action on the ProductController which basically save the product to db but when validation errors occur, I am returning a View(mymodel) else when saved, I am returning RedirectToAction("Created,"Product") but for some odd reason when I break into the code , it is hitting the Product Controller action twice rather than just once. Hence the product has 2 records instead of one.
public ActionResult Index()
{
return View()
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection fc)
{
// 2 calls are made to this controller
try
{
// save the product
return RedirectToAction("Created");
}
catch(Exception ex)
{
// recreate the model from form collection
return View(viewData); // when a validation error occurs it comes into the catch block
}
}
Sometimes I have found Firebug to cause this behavior. Try disabling its Script panel, if you have it installed.
Explanation: In some cases Firebug isn't able to get the script sources for the display within its Script panel. In these cases it initiates a second request to get them. See issue 7401 for some discussion about this, which alleviates the problem and is fixed with Firebug 2.0.2.
Here's a basic checklist (copied from here):
Check that you don’t have any image or another elements in the View with an
empty src attribute (<img src=”" /> for example) or have src
attribute referencing something that no longer exists. You better
check directly in the browser's “Page Source”, than in the View itself due to the
possibility of some “dynamic” issues when the View is rendered. Once you
find such empty element in the page's HTML source its usually trivial to
find the same element in your View and fix the issue. This can also happen with <link href="">.
Check that you don’t have any AJAX calls referencing an empty URL (browsers will interpret such empty URL as the current page and will request the current page again making the Controller action execute few times).
You forgot to return “false” from the JavaScript click event handler for a link or button that makes an AJAX call. If you forget to “return false”, the browser simply interprets the default action of the link – regular, non AJAX, calling the same page again)
Sometimes Firebug and YSlow [ Firefox (FF) plugins ] can cause such issues. Just temporarily disable them in FF or test with a different browser.
Watch out for duplicate filters decorating your controller or action. (this was my problem)
Another solution for this case..
I had exactly same problem, running and testing from Chrome. I couldn't debug it because the second call was coming from (external call). I have randomly tested it in Firefox and Internet Explorer where there was no double hit.
Whatever nasty thing it was, I have deleted Chrome cache (everything!!!) and problem has been resolved.
Hope it will help some of you :)
I had a similar issue with a controller action that generated an image, and I was only seeing it with Firefox. There is a really old bug that causes this, that I guess is still there.
https://bugzilla.mozilla.org/show_bug.cgi?id=304574

Resources