This is an automated email from the ASF dual-hosted git repository. kusal pushed a commit to branch WW-5382-stale-config in repository https://gitbox.apache.org/repos/asf/struts.git
commit 15acd72d240f356685ab2238a0ab4e62130c84ae Author: Kusal Kithul-Godage <g...@kusal.io> AuthorDate: Sun Dec 31 00:29:29 2023 +1100 WW-5382 Fix stale injections in Dispatcher --- .../org/apache/struts2/dispatcher/Dispatcher.java | 47 +++++++++------------- .../apache/struts2/dispatcher/MockDispatcher.java | 19 ++++++++- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java index e378633e2..7234dfe6c 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java @@ -119,6 +119,8 @@ public class Dispatcher { */ private static final List<DispatcherListener> dispatcherListeners = new CopyOnWriteArrayList<>(); + private Container injectedContainer; + /** * Store state of StrutsConstants.STRUTS_DEVMODE setting. */ @@ -331,6 +333,12 @@ public class Dispatcher { this.handleException = Boolean.parseBoolean(handleException); } + @Inject(StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND) + public void setDispatchersParametersWorkaround(String dispatchersParametersWorkaround) { + this.paramsWorkaroundEnabled = Boolean.parseBoolean(dispatchersParametersWorkaround) + || (servletContext != null && StringUtils.contains(servletContext.getServerInfo(), "WebLogic")); + } + public boolean isHandleException() { return handleException; } @@ -536,17 +544,6 @@ public class Dispatcher { return getContainer(); } - private void init_CheckWebLogicWorkaround(Container container) { - // test whether param-access workaround needs to be enabled - if (servletContext != null && StringUtils.contains(servletContext.getServerInfo(), "WebLogic")) { - LOG.info("WebLogic server detected. Enabling Struts parameter access work-around."); - paramsWorkaroundEnabled = true; - } else { - paramsWorkaroundEnabled = "true".equals(container.getInstance(String.class, - StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND)); - } - } - /** * Load configurations, including both XML and zero-configuration strategies, * and update optional settings, including whether to reload configurations and resource files. @@ -567,9 +564,7 @@ public class Dispatcher { init_AliasStandardObjects(); // [7] init_DeferredXmlConfigurations(); - Container container = init_PreloadConfiguration(); - container.inject(this); - init_CheckWebLogicWorkaround(container); + getContainer(); // Inject this instance if (!dispatcherListeners.isEmpty()) { for (DispatcherListener l : dispatcherListeners) { @@ -1068,22 +1063,18 @@ public class Dispatcher { * @return Our dependency injection container */ public Container getContainer() { - if (ContainerHolder.get() != null) { - return ContainerHolder.get(); - } - ConfigurationManager mgr = getConfigurationManager(); - if (mgr == null) { - throw new IllegalStateException("The configuration manager shouldn't be null"); - } else { - Configuration config = mgr.getConfiguration(); - if (config == null) { - throw new IllegalStateException("Unable to load configuration"); - } else { - Container container = config.getContainer(); - ContainerHolder.store(container); - return container; + if (ContainerHolder.get() == null) { + try { + ContainerHolder.store(getConfigurationManager().getConfiguration().getContainer()); + } catch (NullPointerException e) { + throw new IllegalStateException("ConfigurationManager and/or Configuration should not be null", e); } } + if (injectedContainer != ContainerHolder.get()) { + injectedContainer = ContainerHolder.get(); + injectedContainer.inject(this); + } + return ContainerHolder.get(); } } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/MockDispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/MockDispatcher.java index b10014995..500e1b541 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/MockDispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/MockDispatcher.java @@ -19,14 +19,19 @@ package org.apache.struts2.dispatcher; import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; import javax.servlet.ServletContext; -import java.util.HashMap; import java.util.Map; +/** + * We really shouldn't test with this class because it relies on changing the ConfigurationManager mid-lifecycle, + * but retaining the stale injections - this will prevent us from detecting exactly these kind of bugs in our tests... + */ public class MockDispatcher extends Dispatcher { private final ConfigurationManager copyConfigurationManager; + private boolean injectedOnce = false; public MockDispatcher(ServletContext servletContext, Map<String, String> context, ConfigurationManager configurationManager) { super(servletContext, context); @@ -39,4 +44,16 @@ public class MockDispatcher extends Dispatcher { ContainerHolder.clear(); this.configurationManager = copyConfigurationManager; } + + @Override + public Container getContainer() { + if (!injectedOnce) { + injectedOnce = true; + return super.getContainer(); + } + if (ContainerHolder.get() == null) { + ContainerHolder.store(getConfigurationManager().getConfiguration().getContainer()); + } + return ContainerHolder.get(); + } }