查看文章 |
Troubleshooting guide migrating from Struts 2.0.x to 2.1.x About the Migration guide This guide describes how to migrate an existing Struts 2.0.x application to Struts 2.1.x. It is intended to be read from top to bottom but you may skip-ahead to known problems and common exceptions. Please edit this page or provide comments if you encounter additional issues. Update Dependencies 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 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: <repositories> <repository> <id>struts2.1.2-staging</id> <name>Struts 2.1.2 staging repository</name> <layout>default</layout> <url>http://people.apache.org/builds/struts/2.1.2/m2-staging-repository/</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> 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. Update Custom Type Converters Before: After: Interceptors: From To Results: Forgetting to rename an interceptor or result reference will prevent your WebApp from starting. The following is a typical stacktrace for an invalid result type. Migrate plugin configuration A missing DOCTYPE in your Tiles configuration will prevent your WebApp from starting. The following is a typical stacktrace for a missing Tiles DOCTYPE. INFO: Initializing Tiles2 container. . . Nov 22, 2007 11:38:11 AM org.apache.commons.digester.Digester error SEVERE: Parse Error at line 2 column 19: Document is invalid: no grammar found. org.xml.sax.SAXParseException: Document is invalid: no grammar found. Ajax Theme / Dojo 1. Add the Dojo plugin as a new dependency for your project <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-dojo-plugin</artifactId> <version>2.1.1</version> </dependency> For each page there are three tasks to complete: reference the new Dojo tag library Reference the new Dojo Tag Library Before After Many pages will require both the core and dojo tags. The sx: prefix is preferred for the Dojo tags. Update the head tag Before: After: Update all ajax themed tags Before: After: 2008-04-19 14:32:30,475 ERROR [http-8443-Processor23] [[jsp]] Servlet.service() for servlet jsp threw exception org.apache.jasper.JasperException: No tag "datetimepicker" defined in tag library imported with prefix "s" Check inline javascript eg. The following bind will execute scripts within the result when the Submit button is pressed <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"/> Convert EL expressions to OGNL todo: how to convert Forgetting to convert attributes to OGNL expressions will produce exceptions similar to the one below: 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 Missing Properties 2008-04-19 14:21:08,177 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [templateDir] 2008-04-19 14:21:08,177 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [templateDir] 2008-04-19 14:21:08,177 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [templateDir] 2008-04-19 14:21:08,178 WARN [http-8443-Processor25] [OgnlValueStack] Could not find property [org.apache.catalina.jsp_file] eg. Include a new limit category in your log4j.xml file (only log errors or worse): <category name="com.opensymphony.xwork2.ognl.OgnlValueStack"> <priority value="error"/> </category> 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' eg. Include a new limit category in your log4j.xml file (only log errors or worse): <category name="org.apache.struts2.util.TextProviderHelper"> <priority value="error"/> </category> The Configuration API now uses a Builder pattern 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()); Result type "redirect-action" was renamed to "redirectAction": <action name="ScheduleJob" class="com.sag.optimizer.ui.web.action.scheduler.ScheduleJobAction"> <result name="success" type="redirect-action"> <param name="actionName">ListDisplayOptimizationJobStatus</param> </result> <result name="error" type="tiles">webui.requestFailed</result> </action> <action name="ScheduleJob" class="com.sag.optimizer.ui.web.action.scheduler.ScheduleJobAction"> <result name="success" type="redirectAction"> <param name="actionName">ListDisplayOptimizationJobStatus</param> </result> <result name="error" type="tiles">webui.requestFailed</result> </action> <action name="ScheduleJob" class="com.sag.optimizer.ui.web.action.scheduler.ScheduleJobAction"> <result name="success" type="redirect">ListDisplayOptimizationJobStatus.action</result> <result name="error" type="tiles">webui.requestFailed</result> </action> Nov 22, 2007 11:38:11 AM org.apache.tiles.impl.BasicTilesContainer init INFO: Initializing Tiles2 container. . . Nov 22, 2007 11:38:11 AM org.apache.commons.digester.Digester error SEVERE: Parse Error at line 2 column 19: Document is invalid: no grammar found. org.xml.sax.SAXParseException: Document is invalid: no grammar found. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131) This is due to the fact that Tiles 2.0.5 now turns validation on as default. The tiles.xml page before: <?xml version="1.0" encoding="ISO-8859-1" ?> <tiles-definitions/> <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://struts.apache.org/dtds/tiles-config_2_0.dtd"> <tiles-definitions/> Nov 22, 2007 1:54:51 PM freemarker.log.JDK14LoggerFactory$JDK14Logger error SEVERE: Expression parameters.parseContent is undefined on line 45, column 28 in template/ajax/head.ftl. The problematic instruction: ---------- ==> ${parameters.parseContent?string} [on line 45, column 26 in template/ajax/head.ftl] ---------- Java backtrace for programmers: ---------- freemarker.core.InvalidReferenceException: Expression parameters.parseContent is undefined on line 45, column 28 in template/ajax/head.ftl. at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124) at freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:134) Ajax UI tags were moved to the new dojo plugin, use /struts-dojo-tags taglib instead of (or in addition to) /struts-tags: SEVERE: Servlet.service() for servlet jsp threw exception org.apache.jasper.JasperException: /jsp/list/listOptimizationJobStatus.jsp(6,0) Attribute href invalid for tag div according to TLD at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40) at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407) <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="display" uri="http://displaytag.sf.net" %> <%@ taglib prefix="s" uri="/struts-tags"%> <s:url id="jobStatus" includeParams="get" value="/RefreshOptimizationJobStatus.action" /> <s:div id="jobStatus" theme="ajax" href="%{jobStatus}" updateFreq="5000" indicator="indicator"> </s:div> <img id="indicator" src="img/indicator.gif" alt="Loading..." style="display:none"/> <%@ page contentType="text/html; charset=UTF-8" language="java" %> <%@ taglib prefix="s" uri="/struts-tags"%> <%@ taglib prefix="sx" uri="/struts-dojo-tags" %> <s:url var="jobStatus" includeParams="get" value="/RefreshOptimizationJobStatus.action" /> <sx:div id="jobStatus" href="%{#jobStatus}" updateFreq="5000" autoStart="true" indicator="indicator"> </sx:div> <img id="indicator" src="img/indicator.gif" alt="Loading..." style="display:none"/> Note the use of remote div is now through the dojo plugin taglib sx. Other ui tags are also no longer available through the /struts-tags taglib but only through the /struts-dojo-tags taglib: datetimepicker and autocompleter. User-defined converter (subclassing StrutsTypeConverter) will no longer be needed when using datetimepicker: <%@ taglib prefix="s" uri="/struts-tags"%> <s:datetimepicker label="Begin Date" name="beginDate" displayFormat="yyyy.MM.dd"> <%@ taglib prefix="s" uri="/struts-tags"%> <%@ taglib prefix="sx" uri="/struts-dojo-tags" %> <sx:datetimepicker label="Begin Date" name="beginDate" displayFormat="yyyy.MM.dd"> These are now only available if you use the new interceptor named "actionMappingParams".
|