Versions Compared

Key

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

...

Info

There have been significant changes to the Configuration API between 2.0 and 2.1. Third-party plugins for 2.0 may not be compatible with 2.1.x.

Maven users can update their project's pom.xml to reference the new core and plugin versions.
Ensure maven is configured to use the appropriate repository. Non-GA releases are usually available in a staging repositoryEnsure no dependencies in the freemarker groupId are used as the latest version used by Struts is now under the org.freeemarker groupId and will cause classpath conflicts.

If you need releases not considered General Availability you can use a staging repository where they are usually available:

Code Block
<repositories>
    <repository>
      <id>struts2.1.1<id>struts-staging</id>
      <name>Struts 2.1.16 staging repository</name>
      <layout>default</layout>
      <url>http://people.apache.org/builds/struts/2.1.16/m2-staging-repository/</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

Non-Maven users can can download the jars and dependencies in a Distribution 2.1.16

Note

DELETE OLD VERSIONS NOW: It's essential that old versions of the jars are removed from your project as well as the deployment directories. Don't trust your IDE to delete unused versions.
eg. Your application is now be dependent on xwork-2.1.x, not xwork-2.0.x. Ensure xwork-2.0.x is completely removed or you will encounter compile-time and run-time exceptions.

...

Code Block
import com.opensymphony.xwork2.conversion.TypeConversionException;

Note: this may also affect conversion classes listed in the xwork-conversion.properties file.

Update struts.xml Update struts.xml Configuration

Results and Interceptors have been renamed to use camelCase instead of hyphenated names (eg. now redirectAction instead of redirect-action).
Review all custom interceptor stacks, interceptor refs and results in struts.xml and remove the hyphen.

...

  1. reference the new Dojo tag library
  2. update the head tag
  3. update all ajax themed tags
  4. check inline scripts
  5. check inline widgets
    Info

    If this is a major undertaking for your application, it's recommended to modify, test and validate each page one at a time.

Reference the new Dojo Tag Library

...

If your ajax html results contain inline javascript that needs to be executed after updating the DOM, ensure your ajax tags set executeScripts="true" and separateScripts="true". These attributes instruct the widget to search for javascript in the result,

extract it, update the DOM with the result and then execute the javascript.

...

Code Block
<s:submit value="Submit" id="submit3" />
<sx:bind targets="div1" highlightColor="#ffffcc" highlightDuration="500" sources="submit3" 
events="onclick" href="%{#fragment3Url}" errorNotifyTopics="/error" executeScripts="true" 
separateScripts="true"/>

Check inline widgets

...

Note

Forgetting to convert attributes to OGNL expressions will produce exceptions similar to the one below:

Code Block
org.apache.jasper.JasperException: /example.jsp(8,6) According to TLD or attribute directive in tag 
file, attribute value does not accept any expression

Reduce verbose logging

Refactor usage of static methods via OGNL

The default behaviour of allowing access to static methods (via an expression like "@org.somewhere.FooUtls@fooMethod()") has been disabled for security reasons in the 2.1 branch. See https://issues.apache.org/struts/browse/WW-2160 for details. You should either remove these cases, or re-enable the use of static methods explicitly in your configuration by using the struts.ognl.allowStaticMethodAccess property.

Reduce verbose logging

Struts 2.1 introduces more verbose logging than Struts 2.0. While Struts 2.1 introduces more verbose logging than Struts 2.0. While extremely valuable, some users may find these annoying.

...

Code Block
none
none
2008-04-19 14:32:30,106 WARN  [http-8443-Processor23] [TextProviderHelper] The first TextProvider in the ValueStack 
(package.Action) could not locate the message resource with key 'companyDetails.addressId'
2008-04-19 14:32:30,107 WARN  [http-8443-Processor23] [TextProviderHelper] The default value expression 
'companyDetails.addressId' evaluated to '10'

...

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.

...

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.

The web.xml after:

Code Block
	 
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.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.

...