Re: error response on missing allowed-methods in struts.xml
Greg Huber <[email protected]>
| Newsgroups | gmane.comp.jakarta.struts.devel |
|---|---|
| Message-ID | <[email protected]> |
Debugging this, its not related to the allowed methods, if I change
anything in struts.xml and then do a previous on a not allowed DMI. I
get the 404 after configs reload.
In class org.apache.struts2.dispatcher.org.apache.struts2.Dispatcher it
throws a ConfigurationException in serviceAction(..) but further
downstream the DefaultDispatcherErrorHandler has not been initialised
and in methodhandleErrorInDevMode it tries to use the template but its null.
I cannot figure out why the DefaultDispatcherErrorHandleris null after a
reload of the configs. There are other variables from the inject but
the init ( init(ServletContext ctx) ) has not been called.
A fix is to add errorHandler.init(servletContext); after
logConfigurationException(request, e);, but does not resolve the init()
being called on DefaultDispatcherErrorHandler.
###
snip >> org.apache.struts2.dispatcher.org.apache.struts2.Dispatcher
public void serviceAction(HttpServletRequest request,
HttpServletResponse response, ActionMapping mapping)
throws ServletException {
.....
} catch (ConfigurationException e) {
logConfigurationException(request, e);
errorHandler.init(servletContext); <<<< NEED THIS CALL
sendError(request, response,
HttpServletResponse.SC_NOT_FOUND, e);
} catch (Exception e) {
...'
}
snip >> org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler
protected void handleErrorInDevMode(HttpServletResponse response, int
code, Exception e) {
....
Writer writer = new StringWriter();
template.process(createReportData(e, chain), writer); <<< TEMPLATE IS NULL
...
}
#####
org.apache.struts2.dispatcher.org.apache.struts2.Dispatcher
public void serviceAction(HttpServletRequest request,
HttpServletResponse response, ActionMapping mapping)
throws ServletException {
Map<String, Object> extraContext = createContextMap(request,
response, mapping);
// If there was a previous value stack, then create a new copy
and pass it in to be used by the new Action
ValueStack stack = (ValueStack)
request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
boolean nullStack = stack == null;
if (nullStack) {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
stack = ctx.getValueStack();
}
}
if (stack != null) {
extraContext = ActionContext.of(extraContext)
.withValueStack(valueStackFactory.createValueStack(stack))
.getContextMap();
}
try {
String actionNamespace = mapping.getNamespace();
String actionName = mapping.getName();
String actionMethod = mapping.getMethod();
LOG.trace("Processing action, namespace: {}, name: {},
method: {}", actionNamespace, actionName, actionMethod);
ActionProxy proxy = prepareActionProxy(extraContext,
actionNamespace, actionName, actionMethod);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY,
proxy.getInvocation().getStack());
// if the ActionMapping says to go straight to a result, do it!
if (mapping.getResult() != null) {
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
proxy.execute();
}
// If there was a previous value stack then set it back
onto the request
if (!nullStack) {
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
}
} catch (ConfigurationException e) {
logConfigurationException(request, e);
sendError(request, response,
HttpServletResponse.SC_NOT_FOUND, e);
} catch (Exception e) {
if (handleException || devMode) {
if (devMode) {
LOG.debug("Dispatcher serviceAction failed", e);
}
sendError(request, response,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
} else {
throw new ServletException(e);
}
}
}
#####
org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler
protected void handleErrorInDevMode(HttpServletResponse response, int
code, Exception e) {
LOG.debug("Exception occurred during processing request: {}",
e.getMessage(), e);
try {
List<Throwable> chain = new ArrayList<>();
Throwable cur = e;
do {
chain.add(cur);
} while ((cur = cur.getCause()) != null);
Writer writer = new StringWriter();
template.process(createReportData(e, chain), writer);
response.setContentType("text/html");
response.getWriter().write(writer.toString());
response.getWriter().close();
} catch (Exception exp) {
try {
LOG.debug("Cannot show problem report!", exp);
response.sendError(code, "Unable to show problem
report:\n" + exp + "\n\n" + LocationUtils.getLocation(exp));
} catch (IOException ex) {
// we're already sending an error, not much else we can
do if more stuff breaks
LOG.warn("Unable to send error response, code: {};",
code, ex);
} catch (IllegalStateException ise) {
// Log illegalstate instead of passing unrecoverable
exception to calling thread
LOG.warn("Unable to send error response, code: {};
isCommited: {};", code, response.isCommitted(), ise);
}
}
}
###
Ok, it seems be a dev mode thing.
If I starup with it set
<allowed-methods>..previous</allowed-methods>
it seems to work, then if I remove it
<allowed-methods>..previousZ</allowed-methods>
it then seems to cause the 404 to show.
On 31/10/2024 14:16, Łukasz Lenart wrote:
> I just checked locally and it looks good with the latest Struts 7
> SNAPSHOT, I would assume you must have some Freemarker leftovers, do
> you use Maven to control dependencies?
>
> czw., 31 paź 2024 o 14:43 Greg Huber<[email protected]> napisał(a):
>> Testing with v7 m9.
>>
>> Try with a method present but with and a missing *<allowed-methods>*
>>
>> I see this 404:
>>
>> Unable to show problem report: java.lang.NullPointerException: Cannot
>> invoke "freemarker.template.Template.process(Object, java.io.Writer)"
>> because "this.template" is null Class:
>> org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler File:
>> DefaultDispatcherErrorHandler.java Method: handleErrorInDevMode Line:
>> 118 -
>> org/apache/struts2/dispatcher/DefaultDispatcherErrorHandler.java:118:-1
>>
>> in the log
>>
>> 2024-10-31 13:40:19,370 ERROR org.apache.struts2.dispatcher.Dispatcher
>> Dispatcher:logConfigurationException - Could not find action or result:
>> /my/mySelect.action
>>
>> com.opensymphony.xwork2.config.ConfigurationException: Method previous
>> for action mySelect is not allowed!
>>
>> On 31/10/2024 12:57, Lukasz Lenart wrote:
>>> 404 is good, NPE is bad, let me try to reproduce this.
>>>
>>> pt., 25 paź 2024 o 12:56 Greg Huber<[email protected]> napisał(a):
>>>> I noticed, if I have a missing allowed-methods in my struts.xml for DMI,
>>>> I get this 404 error
>>>>
>>>> Status Code 404
>>>>
>>>> Message: Unable to show problem report: java.lang.NullPointerException
>>>> Class: org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler File:
>>>> DefaultDispatcherErrorHandler.java Method: handleErrorInDevMode Line:
>>>> 118 -
>>>> org/apache/struts2/dispatcher/DefaultDispatcherErrorHandler.java:118:-1
>>>>
>>>>
>>>> In the log file it shows:
>>>>
>>>> 2024-10-25 11:47:38,778 ERROR org.apache.struts2.dispatcher.Dispatcher
>>>> Dispatcher:logConfigurationException - Could not find action or result:
>>>> /me/myAction.action
>>>>
>>>> com.opensymphony.xwork2.config.ConfigurationException: Method previous
>>>> for action myAction is not allowed!
>>>>
>>>> at
>>>> com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:191)
>>>> ~[classes/:?]
>>>>
>>>> Is the 404 NPE exception correct/expected?
>>> ---------------------------------------------------------------------
>>> To unsubscribe,e-mail:[email protected]
>>> For additional commands,e-mail:[email protected]
>>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:[email protected]
> For additional commands, e-mail:[email protected]
>