Upgrade to Struts 2.5

Expanders 4.2.0+ will use Struts 2.5. Also required for this are baseComponents 2020.2.0+ and nsx-runtime 2020.2.0+ (provided by prime-data 2020.2.0+).

The reason for the upgrade is security, as previous versions of struts contain critical vulnerabilities:

https://nvd.nist.gov/vuln/detail/CVE-2018-1327

Artifacts Changed

Expanders:

  • web.xml (updated package for StrutsPrepareAndExecuteFilter)
  • struts xml files (updated dtd reference)

baseComponents:

  • AccessInfoRetrieverAction (ActionContext::getParameters() has a different return type)

nsx-runtime

  • TranslateTextAction (Uses StrutsLocalizedTextProvider instead of LocalizedTextUtil)

Infrastructure

TomEE 7.0.4

Old apache-commons-lang3 library throws java.lang.NoSuchMethodError. Upgrade TomEE to version 7.1.1+ or manually update lib/commons-lang3-3.5.jar to lib/commons-lang3-3.8.1.jar.

Custom Code

Listing of known issues encountered during migrations and how to fix them.

ActionSupport.LOG

Custom struts actions using LOG of com.opensymphony.xwork2.ActionSupport, possibly due to copy-pasting.

Fix: Create class-specific logger.

// old code
class MyStrutsAction extends ActionSupport {
  public String execute() {
    LOG.info("...");
  }
}

// replacement code
class MyStrutsAction extends ActionSupport {
  private Logger logger = LoggerFactory.getLogger(MyStrutsAction.class);
  public String execute() {
    logger.info("...");
  }
}

Overriding Parameters in Struts Interceptors

// old code
ActionContext.getContext().getParameters().put($key$, $value$);

// replacement code (for structural replace)
java.util.Map<String, org.apache.struts2.dispatcher.Parameter> newParams = new java.util.HashMap<String, org.apache.struts2.dispatcher.Parameter>();
newParams.put($key$, new org.apache.struts2.dispatcher.Parameter.Request($key$, $value$));
ActionContext.getContext().getParameters().appendAll(newParams);

Directly invoking LocalizedTextUtil

Replacements can be applied via IntelliJ’s Structural Replace action.

LocalizedTextTranslator is available in nsx-runtime/nsx-presentation-struts2 v2020.4.0+

// old code
LocalizedTextUtil.findDefaultText($KEY$, $LOCALE$)

// replacement code within StrutsAction with current locale
getText($KEY$)

// replacement code within StrutsAction with DIFFERENT locale
net.democritus.utils.LocalizedTextTranslator.findText(getContainer(), $KEY$, $LOCALE$)

// replacement code outside of StrutsAction
net.democritus.utils.LocalizedTextTranslator.findText($KEY$, $LOCALE$)

// hand-constructed replacement directly invoking/dependning on struts classes
Container container = ServletActionContext.getContext().getContainer();
LocalizedTextProvider localizedTextProvider = container.getInstance(com.opensymphony.xwork2.LocalizedTextProvider.class);
String value = localizedTextProvider.findText(TextProviderSupport.class, $KEY$, $LOCALE$, (String)null, new Object[0]);

https://cwiki.apache.org/confluence/display/WW/Struts+2.3+to+2.5+migration