When upgrading my application to use Spring Boot version 2.1.8.RELEASE + struts2-convention-plugin with Struts2-core version 2.5.20 the actions are not being mapped correctly and I am getting the error
com.opensymphony.xwork2.config.ConfigurationException: There is no Action mapped for namespace [/] and action name [home] associated with context path [].
If I decalre the actions in struts.xml
they work perfectly.
Below is my current configuration, why are they not mapping?
I have tried many diffrent configs and nothing seems to work, the StrutsPrepareAndExecuteFilter
is firing but not actions are found, as if Spring has not scanned them. Could this be a dependency version issue?
application.yaml
server:
port: 8080
servlet:
context-path: /
Struts2.xml
<struts>
<constant name="struts.devMode" value="false" />
<constant name="struts.convention.action.packages" value="com.myactions.action" />
<constant name="struts.convention.action.includeJars" value=".*?/myjar.*?jar(!/)?,.*?/myjar*?jar(!/)?" />
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.objectFactory.spring.autoWire" value="name" />
<constant name="struts.multipart.maxSize" value="100000000" />
<constant name="struts.convention.default.parent.package" value="struts-default"/>
## THIS WORKS
<!-- <package name="home" extends="struts-default">-->
<!-- <action name="actionHome" class="com.myactions.action.HomeController" method="actionHome">-->
<!-- <result name="success">home.jsp</result>-->
<!-- </action>-->
<!-- </package>-->
</struts>
Controller
@Namespace("/")
public class HomeController extends BaseController {
@Action("home")
public String actionHome() throws Exception {
return SUCCESS;
}
}
Main
@SpringBootApplication
@ServletComponentScan
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
return springApplicationBuilder.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Struts2 Filter
@WebFilter("/*")
public class Struts2Filter extends StrutsPrepareAndExecuteFilter {
}
UPDATE
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 :
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 :
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 I'm able to access the configured actions with no more XML.
UPDATE
After the OP's 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 [...]