Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Code Block
xml
xml
<category name="org.apache.struts2.util.TextProviderHelper">
      <priority value="error"/>
   </category>

Update Unit Tests

There are two known major migration issues affecting user's unit tests.

  • The Configuration API now uses a Builder pattern
  • The ActionContext.getContext() method does not create a context on demand.

Review the Unit Tests included with Struts2 for recommended practices to setup the Configuration and context.

A quick fix for ActionContext.getContext() returning null :

...


        ConfigurationManager configurationManager = new ConfigurationManager();
        configurationManager.addContainerProvider(new XWorkConfigurationProvider());
        Configuration config = configurationManager.getConfiguration();
        Container container = config.getContainer();

        ValueStack stack = container.getInstance(ValueStackFactory.class).createValueStack();
        stack.getContext().put(ActionContext.CONTAINER, container);
        ActionContext.setContext(new ActionContext(stack.getContext()));

        assertNotNull(ActionContext.getContext());

Redirect and RedirectAction parameters

A (incorrect) change in 2.1.6 has ObjectFactory reporting ERROR's when you attempt to set parameters on a Redirect result.

So a redirect result that sets a parameter like this:

Code Block

<result type="redirectAction">
	<param name="actionName">MyAction</param>
	<param name="xxx">${xxx}</param>
</result>

Will always give you an error like this:

Code Block

2009-03-04 16:44:54,201 ERROR com.opensymphony.xwork2.ObjectFactory:27 - Unable to set parameter [xxx] in result of type [org.apache.struts2.dispatcher.ServletActionRedirectResult]
Caught OgnlException while setting property 'xxx' on type 'org.apache.struts2.dispatcher.ServletActionRedirectResult'. - Class: ognl.ObjectPropertyAccessor
File: ObjectPropertyAccessor.java
Method: setProperty
Line: 132 - ognl/ObjectPropertyAccessor.java:132:-1
	at com.opensymphony.xwork2.ognl.OgnlUtil.internalSetProperty(OgnlUtil.java:392)
	at com.opensymphony.xwork2.ognl.OgnlUtil.setProperty(OgnlUtil.java:143)
	at com.opensymphony.xwork2.ognl.OgnlReflectionProvider.setProperty(OgnlReflectionProvider.java:91)
	at com.opensymphony.xwork2.ObjectFactory.buildResult(ObjectFactory.java:221)
	at com.opensymphony.xwork2.DefaultActionInvocation.createResult(DefaultActionInvocation.java:208)
	at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:355)

You can safely ignore and suppress the error by setting the logging level to 'fatal' like this:

Code Block
xml
xml

<category name="com.opensymphony.xwork2.ObjectFactory">
   <priority value="fatal"/>
</category>

Update Unit Tests

There are two known major migration issues affecting user's unit tests.

  • The Configuration API now uses a Builder pattern
  • The ActionContext.getContext() method does not create a context on demand.

Review the Unit Tests included with Struts2 for recommended practices to setup the Configuration and context.

A quick fix for ActionContext.getContext() returning null :

Code Block
java
java

        ConfigurationManager configurationManager = new ConfigurationManager();
        configurationManager.addContainerProvider(new XWorkConfigurationProvider());
        Configuration config = configurationManager.getConfiguration();
        Container container = config.getContainer();

        ValueStack stack = container.getInstance(ValueStackFactory.class).createValueStack();
        stack.getContext().put(ActionContext.CONTAINER, container);
        ActionContext.setContext(new ActionContext(stack.getContext()));

        assertNotNull(ActionContext.getContext());

Explicitly set the includeParams attribute on all url tags to "get" if it is not specified.

The default value of this attribute changed from "get" to "none". See https://issues.apache.org/struts/browse/WW-2901

Filter Mapping, default Action extensions, and Servlets

The default action extension list (struts.action.extension) has changed from just 'action' to 'action' plus "" (no extension). If your application has servlets or other requests that have no extension then they will be mistaken as actions and you will get a "There is no Action mapped for ..." exception like below.

Code Block

There is no Action mapped for namespace / and action name xxxx. - [unknown location]
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:177)
    at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
    at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:47)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:458)
    at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)

To fix this problem you can explicitly set the default action extension back to just "action" or you can change your filter mapping for the struts filter.

To set the action extension list back to just "action" add this to your struts.xml file:

Code Block

<constant name="struts.action.extension" value="action" />

If all your actions use the ".action" suffix then you may want to change the Struts filter-mapping so that only actions are handled by the struts filter. Also the FilterDispatcher has been deprecated and replaced by StrutsPrepareAndExecuteFilter.

The web.xml before (matching all requests):

Code Block
	 
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>

<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

Change to use the new StrutsPrepareAndExecuteFilter and match just struts requests

Explicitly set the includeParams attribute on all url tags to "get" if it is not specified.

The default value of this attribute changed from "get" to "none". See https://issues.apache.org/struts/browse/WW-2901

Filter Mapping and Servlets

If your application also has servlets you may need to adjust the Struts filter-mapping to allow the requests through to your servlets.

With 2.0.11 you could have your struts filter configured to match all requests and those that did not have a .action suffix would be passed through to your servlets.

The web.xml before:

Code Block
	 
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>

<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

With 2.1.6 it appears that the struts filter attempts to match all requests to actions even if they do not have a .action suffix (even when not using the conventions plugin.) If you have non-action requests then you may need to modify the struts filter mapping so that only action requests are matched. In the example below I've changed the url-pattern to be "*.action" since I only want requests with a .action suffix to be handled by struts.

The web.xml after:

Code Block
	 
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.FilterDispatcher<ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>*.action</url-pattern>
</filter-mapping>

<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/struts/*</url-pattern>
</filter-mapping>

Trouble-shooting

The issues are listed in the same order as encountered after changing jars over from 2.0.x to 2.1.x. Noteworthy, the migration was done under the following setup: Fedora core 6, JDK 1.6.0_2 and Tomcat 6.0.10 running from MyEclipse plugin.

...