[ 
https://issues.apache.org/jira/browse/WICKET-3302?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12977268#action_12977268
 ] 

Willis Blackburn commented on WICKET-3302:
------------------------------------------

I know that it's supposed to work that way because I read about people having 
this problem before.  I did some more investigation and discovered that the 
exception from LDM.load is only the instigator.  The cause of the recursion is 
that after the first invocation of the Component's isVisible method, which 
calls LDM.load and generates the exception, subsequent calls generate NPE, 
because the LDM.getObject now returns null.  The recursion continues until 
either we blow the stack or run out of heap.  Since this happens in less than a 
second normally, it sort of looks like the exception has worked and has aborted 
the page render, but the requested status code never gets sent back to the 
browser.

I think that catching exceptions in Component.toString would be a good idea and 
would resolve this issue and many future issues.  Throwing an exception from 
the getDefaultModelObject method for any reason (whether it's due to LDM.load 
or from some custom model code) leaves the component's model in an unknown 
state, which means that any call to any non-final method of Component might 
generate an exception, which in turn will lead to the stack and/or heap being 
blown.

I guess you could say "well it's the programmer's responsibility to check for a 
null model," but this seems unreasonable in light of the circumstances:

1.  The programmer is throwing an exception from LDM.load specifically because 
he doesn't want to deal with having a null model.  If the code was prepared to 
deal with a null model, then the programmer could just return null from 
LDM.load and let the page render and/or handle the condition in some other 
manner.

2.  If the programmer has thrown AbortWithHttpErrorCodeException, then he 
reasonably expects the request to *abort*, not to call additional component 
methods.  There is no compelling reason why Wicket can't just set the HTTP 
status and commit the response.

3.  The method that is leading to the recursion is a *diagnostic* method 
(toString), not one that's part of Wicket's core logic.  The programmer should 
not have to add "if (model != null) ..." throughout his code merely to support 
a log message.  If Wicket wants to print some diagnostics about a component 
with a known-bad model, then it should handle the potential exceptions.  The 
programmer, who has tried to avoid working with a bad model by thrown an 
exception from LDM.load, should not have to write defensive code anyway to 
support Component, which is choosing to continue to invoke methods on itself 
despite the model having failed to initialize.

W







> Endless recursion if LoadableDetachableModel.load throws exception
> ------------------------------------------------------------------
>
>                 Key: WICKET-3302
>                 URL: https://issues.apache.org/jira/browse/WICKET-3302
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.5-M3
>            Reporter: Willis Blackburn
>
> I don't know if there's any easy fix for this, but here's what happens:
> 1. Component subclass overrides isVisible with a new implementation that 
> depends on the current model state.
> 2. The model is a LoadableDetachableModel.
> 3. On the initial render, the load method of the LoadableDetachableModel 
> throws a RuntimeException for whatever reason.  (In my case I was trying to 
> throw a AbortWithHttpErrorCodeException.)
> 4. This gets caught in Component.getDefaultModelObject:
>     log.error("Error while getting default model object for Component: " + 
> this.toString(true));
> 5.  The toString method that's invoked from the exception handler prints the 
> component's state, including its visibility.
> 6.  In order to resolve the visibility state, toString has to call 
> isVisible--the same method that initially caused the exception.
> 7.  The isVisible method again throws an exception, etc.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to