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]
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.