java – Struts2 Convention Plugin @Actions not mapping with Spring Boot
java – Struts2 Convention Plugin @Actions not mapping with Spring Boot
After a couple days of trials and errors, here are a few clues.
Spring Boot 2.1.8 with Struts 2.5.20 configured with struts.xml works.
Your projet POM requires at least the following dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.8</version>
</dependency>
...
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.5.20</version>
</dependency>
I would also recommend adding the Config Browser Plugin to easily list the available actions:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-config-browser-plugin</artifactId>
<version>2.5.20</version>
</dependency>
It works when you package :
- a fat JAR with an embedded Tomcat server, which is the default behavior
- a WAR in an external Tomcat Server
To get rid of struts.xml and configure your actions only through Java classes, the Convention plugin is required:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.5.20</version>
</dependency>
Notes :
- the constant defined in struts.xml can also be migrated to the struts.properties file (default values listed here)
- struts.xml takes precedence over the Convention plugin and struts.properties
When struts.xml is removed, the Convention plugin takes over and Action classes are mapped using the name of packages and classes. The default conventions (action-to-URL mappings, result path…) can also be overridden thanks to a set of annotations.
Still, as mentioned by the OP, configuration through annotations does NOT work out of the box with an embedded Tomcat (it does with an external Tomcat, though).
Best I could do so far, is make it work using an embedded Jetty instead of Tomcat, and adding the recommended configuration to struts.properties:
struts.convention.exclude.parentClassLoader=false
struts.convention.action.fileProtocols=jar,code-source
The starting log still shows errors, but Im able to access the configured actions with no more XML.
UPDATE
After the OPs update, I digged in a bit more. It turns out the Convention Plugin works fine with Tomcat embedded and no XML needed, by doing the following:
-
Adding the following line to the struts.properties
struts.convention.exclude.parentClassLoader=false
-
Upgrading asm modules asm, asm-commons and asm-tree to release 6.2 or later to prevent errors similar to
ERROR org.apache.struts2.convention.DefaultClassFinder.<init>:95 - Unable to read class [...]
Having stepped through spring2-convention-plugin
the class PackageBasedActionConfigBuilder
has a method buildUrlSet
which gets all the urls
to classes that need to be scanned for Actions
this was removing the urls
to my classes and hence nothing was being scanned.
There is a condition excludeParentClassLoader
which needs to be set to false
(line 415).
Solution
Set below constants to –
<constant name=struts.convention.exclude.parentClassLoader value=false />
<constant name=struts.convention.action.fileProtocols value=jar,code-source />