1

I have an old project which uses xml configured struts2 mappings. I wanted to make it a bit fresher and use annotations mapping, as would do that in spring mvc. So I found, that struts2 allows that. But after I added

    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-convention-plugin</artifactId>
        <version>${org.apache.struts.version}</version>
    </dependency>

to my pom xml. My xml configuration stopped working.

Here is what I have in my struts.xml:

    <action name="my/home" class="my.dhblah.MyAction">
        <result type="redirectAction">my/home/search</result>
    </action>

I removed plugin from maven pom. I debugged struts and what I see in DefaultActionInvocation.createResult() on line proxy.getConfig() is the following:

result = {com.opensymphony.xwork2.config.entities.ActionConfig@10444}"{ActionConfig my/home (my.dhblah.MyAction) - null}"
interceptors = {java.util.Collections$UnmodifiableRandomAccessList@10447} size = 20
params = {java.util.Collections$UnmodifiableMap@10448} size = 0
results = {java.util.Collections$UnmodifiableMap@10449} size = 2
exceptionMappings = {java.util.Collections$UnmodifiableRandomAccessList@10450} size = 1
className = {java.lang.String@10451}"my.dhblah.MyAction"
methodName = null
packageName = {java.lang.String@10452}"my"
name = {java.lang.String@10453}"my/home"
allowedMethods = {java.util.Collections$UnmodifiableSet@10454} size = 1
location = null

when I expand "results" section I see two results mapping "success" and "exception"

After I enable plugin in pom.xml I see the following on the same line:

config = {com.opensymphony.xwork2.config.entities.ActionConfig@10457}"{ActionConfig home (my.dhblah.MyAction.execute()) - null}"
interceptors = {java.util.Collections$UnmodifiableRandomAccessList@10460} size = 18
params = {java.util.Collections$UnmodifiableMap@10461} size = 0
results = {java.util.Collections$UnmodifiableMap@10462} size = 0
exceptionMappings = {java.util.Collections$UnmodifiableRandomAccessList@10463} size = 0
className = {java.lang.String@10464}"my.dhblah.MyAction"
methodName = {java.lang.String@10395}"execute"
packageName = {java.lang.String@10465}"my.dhblah#convention-default#/my"
name = {java.lang.String@10466}"home"
allowedMethods = {java.util.Collections$UnmodifiableSet@10467} size = 1
location = null

and after I hit that url I have the following error:

Struts Problem Report

Struts has detected an unhandled exception:

Messages:   
No result defined for action my.dhblah.MyAction and result success
Stacktraces

No result defined for action my.dhblah.MyAction and result success
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167)

I didn't add @Actionannotation to MyAction, but it appears that convention-plugin picks up old Action classes and builds mapping configuration before it looks on xml configuration, that's why I have an error that nothing is mapped on "success" result.

Does anybody had this problem and how to solve it?

Roman C
  • 49,761
  • 33
  • 66
  • 176
dhblah
  • 9,751
  • 12
  • 56
  • 92
  • `I wanted to make it a bit fresher and use annotations mapping` you should then drop all the old XML configuration, and put the annotations wherever needed. Convention otherwise will scan each action, not only the annotated ones, and messing the configuration. – Andrea Ligios Sep 12 '14 at 12:17
  • Yes, this appears to be the problem, I checked with "config browser plugin" and it appears that in addition to actions defined in struts.xml, there are also that same actions mapped on various namespaces created by convention plugin. I'll try to make convention plugin not to search not annotated classes. – dhblah Sep 12 '14 at 13:06
  • 2
    MMMMMMMmmmmmhhhh. You take a project with no annotation and xml config, add convention plugin, avoid refactoring old xml to new annotations, and then try to hack convention plugin to bypass old classes... sounds like a Bad Idea™ to me. If you are doing minor upgrades to the project, then stick to the old xml config. If you have to "double the project size", then refactor everything... both ways are cleaner and [KISS compliant](http://en.wikipedia.org/wiki/KISS_principle) – Andrea Ligios Sep 12 '14 at 13:11

1 Answers1

1

These are different action configs. However when you map your action via the Struts configuration the logic to retrieve the action mapping is implemented and performed by the action mapper. There's a default implementation of action mapper that is used by default. You should know that convention plugin appends its configuration to the xml configuration. So you might have duplicate actions configured at runtime. It's difficult to predict which configuration elements will be picked up by the action mapper to build the action mapping. To solve this kind of configuration problems you can use Config Browser Plugin.

The Config Browser is a simple tool to help view your Struts configuration at run-time. It is very useful when debugging problems that could be related to configuration issues.

To install the plugin just add it to the dependency

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-config-browser-plugin</artifactId>
    <version>${org.apache.struts.version}</version>
</dependency>

This plugin can be installed by copying the plugin jar into your application's /WEB-INF/lib directory.

Roman C
  • 49,761
  • 33
  • 66
  • 176