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<gregh3...@gmail.com>  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<gregh3...@gmail.com>   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:dev-unsubscr...@struts.apache.org
For additional commands,e-mail:dev-h...@struts.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail:dev-unsubscr...@struts.apache.org
For additional commands, e-mail:dev-h...@struts.apache.org

Reply via email to