Contents

What's new in the Apache Struts 6.0.0

What's new in the Apache Struts 6.0.0 webp image

The short answer is: a lot :) If you take a look at the Version Notes, you can notice over 200 changes - tons of bug fixes and improvements with a pinch of new features. Nevertheless, the most important change is the proper usage of the Semantic Versioning - this can be a surprise for most of you.

Versioning schema

You can ask: why did we change the versioning schema? Previously we had been using Struts 2.3.x, 2.5.x, and the next version was supposed to be 2.6.x - but as you can notice we are missing one advantage of semantic versioning: changing the MAJOR part of the version. The Apache Struts 2 is a different framework than Struts 1 and its versioning should have started with 1.0.0, yet this never happened. With each release containing breaking changes (like Struts 2.5), we had been only upgrading the MINOR part of the version, MAJOR had been fixed to 2.

That's why we decided to break with such a tradition and stick to a proper SemVer policy. You can expect new 6.0.1 or 6.1.0 and even 7.0.0 in the near future :)

The most important changes

Servlet API 3.1

The Apache Struts isn't the first choice for new and modern applications, but it still has many users, which do not want to rewrite everything from scratch every 2-3 years ;-) That's why some changes are introduced slower, in a more steady manner. Until version 6.0.0, each application using Struts had to use Java Servlet API 2.5 at least. This version of Servlet API is over 17 years old now, while Struts is 20 years old :D

As we wanted to support Async Actions, which requires to use of Servlet API 3.0, and we had been struggling with some other interdependencies, we decided to switch to Servlet API 3.1. This requires to use of an adequate version of a Servlet Container that supports the given Servlet API. Still, we didn't utilize the whole functionality of the new Servlet API, but we have an open path to do so.

Freemarker

Freemarker is a powerful templating engine used by Struts to render tags. That's right, each Struts tag has been implemented as a Freemarker template and if you want to you can override the default template of each tag, either by defining a new theme or just by providing a new template. See the docs for more details.

The latest version of Freemarker introduces an Autoescaping feature. This feature has been enabled by default and automatically escapes all the provided values to be properly rendered as HTML. You don't have to anymore use the ?escape or ?html directives, your templates can be more robust and clean. However, this feature breaks backward compatibility. Many templates produce also JavaScript code and autoescaping just breaks them, the output isn't valid JavaScript anymore. To avoid such problems you must use a valid output format - the simplest way is to use the <#outputformat/> directive as depicted below:

<#if parameters.onclick??>
 onclick="<#outputformat 'JavaScript'>${parameters.onclick}</#outputformat>"<#rt/>
</#if>

This will ensure your template produces a valid JavaScript handle. Switching to the latest version also broke all the plugins, which depended on Freemarker like JQuery plugin or Bootstrap plugin. When writing this post, all those plugins should be already compatible with Struts 6.0.0.

OGNL Sandbox

The Apache Struts has an infamous history of a lot of nasty security vulnerabilities around the usage of the OGNL expression language. OGNL is a very powerful tool, and it affects almost all aspects of the framework. For years, we have been working hard on improving how Struts is using OGNL, despite this new security holes have been detected by researchers from time to time. One of our committers proposed an ultimate solution to protect customers' systems - an OGNL sandbox. He introduced a set of improvements to OGNL as well and adjusted the Struts code to use the new security options.

Right now just by adding -Dognl.security.manager to the JVM startup parameters you can protect your systems from any feature attacks based on OGNL as a breakage vector. This a very powerful limitation and you must test your app very carefully.

Some time ago we introduced an option to limit the length of OGNL expressions, but it wasn’t defined (and probably most of the users haven’t defined it). With this major version, we set the limit to 256 characters. Also, support for accessing static methods via @ quantifier has been removed.

We're constantly updating our Security guide to make your applications even more secure. Please take time and read through our recommendations.

Support Java 11 & 17

As Apache Struts 6.0.0 requires at least Java 8 to run, we put a lot of effort to support running the framework on the latest JVM versions. As you might know, Java 9 & 11 introduced restrictions on using Reflection API in Java. Most often it isn't a problem in the framework itself, but in dependencies like ASM or Javassist libraries.

We have ongoing CI builds on JDK 11 and 17 to be sure everything will work smoothly for early adopters.

Other changes

Besides these enormous changes, we have introduced a lot of other smaller things that can be helpful to the users. I enlisted the most important below.

Deprecations

We decided to mark some plugins as deprecated - the development of related technology has ended or no one is using it. This should allow us to introduce new features and functions without a need to support outdated technologies.

  • EmbeddedJSP plugin, which allows to implement Actions with JSPs and store them in a Jar file, it was a nice thing but no one used it
  • GXP plugin, support for Google XML Pages - I'm not joking, Google invented something like this, see the code, rather a dead-end solution
  • OSGi plugin, as OSGi technology is still in use, almost no one uses it in normal web applications, and is better to focus on supporting Java Modules (after migrating to Java 11)
  • OVal Plugin, OVal stands for the object validation framework for Java, yet replaced by Bean Validations specifications.
  • Plexus Plugin, in the old times' everyone wanted to invent a new shiny IoC container, Plexus was one of them
  • Portlet plugin (and related plugins), Portlet supposed to revolution building dynamic Web UI services, but we all know how it ended
  • Sitemesh Plugin, Sitemesh is a web page layout system, which used decorators to compose the final output, yet no one is supporting it now

As Struts assimilated XWork a long time ago, we are in a constant task of merging the code base and removing references to the old XWork code. In Struts 6.0.0 we dropped support for all the XWork constants as most of them have proper substitutes.

Also, take a look at some deprecated interfaces as you must adjust your code to start using the new one.

A new result

The Apache Struts consists of actions and results, where actions have been used to build logic, while results represent the view. In a classic app, the view layer is developed around HTML, yet modern services can produce output in different formats.

In Struts 6.0.0 you can use a Plain result type, which uses Java code to directly write from action to the output:

public class UserAction {

    private String id;

    public PlainResult execute() {
        return response -> response.write("User Id: " + id);
    }

    public PlainResult html() {
        return response -> response.write("<b>test</b>").withContentTypeTextHtml();
    }

}

Please explore the API of the result to find more useful methods.

Content Security Policy support

Each modern web application must support Content Security Policy and related technologies. In Struts 6.0.0 such a mechanism has been introduced by implementing a set of interceptors:

All these interceptors have been defined in the default stack and set in report mode. You should use them if possible and if you have no knowledge about CSP it's about time to grasp it :)

Summary

As you might see, this version of the Apache Struts brings a lot of changes in many areas. It took almost two years to address all the issues and tasks in JIRA. Even though we had to narrow the scope and postpone some changes to the next releases.

I already mentioned that the Apache Struts isn't dead yet, and you can expect a stable evolution of the framework. Not so many technologies are still in use after 20 years :)

Blog Comments powered by Disqus.