[
https://issues.apache.org/jira/browse/WW-4105?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
zhouyong updated WW-4105:
-------------------------
Description:
java.lang.ClassCastException: A action cannot be cast to B action when A chain
to B.
ChainingInterceptor.java has a bug in intercept function when Result type is
chain.
Intercept function of ChainingInterceptor will change action member of
DefaultActionInvocation class. And invokeAction of DefaultActionInvocation will
fail in line 450.
My action class has a annotation. It is
org.springframework.transaction.annotation.Transactional. Action work good
if it has not org.springframework.transaction.annotation.Transactional
AtestAction.java:
package demo.action;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@ParentPackage(value="swordlite")
@Service("AtestAction")
@Scope(value = "prototype")
@Results( {
@Result(name = "test", location = "testb", type = "chain",
params = {
"defineId", "${_defineId}",
"rp", "${_resultPage}"}
)
})
public class AtestAction {
@Action(value = "/testa")
public String run() throws Exception
{ return "test"; }
}
BtestAction.java:
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@ParentPackage(value="swordlite")
@Service("BtestAction")
@Scope(value="prototype")
@Results({
@Result(name="ok", location="/ok.jsp", type="dispatcher"),
})
public class BtestAction {
@Action(value = "/testb")
public String run() throws Exception
{ return "ok"; }
}
request: http://localhost:8080/test/testa.action
raise error: java.lang.ClassCastException: demo.action.AtestAction cannot be
cast to demo.action.BtestAction
spring config file: applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<context:component-scan base-package="..action,.**.spring" />
<context:annotation-config />
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>WEB-INF/config/db.properties</value>
<value>WEB-INF/config/hibernate.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${database.working.driver}"></property>
<property name="jdbcUrl" value="${database.working.url}"></property>
<property name="user" value="${database.working.user}"></property>
<property name="password" value="${database.working.password}"></property>
<property name="maxPoolSize" value="${database.working.poolsize}"></property>
<property name="minPoolSize" value="1"></property>
<property name="initialPoolSize" value="1"></property>
<property name="maxIdleTime" value="20"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>.*.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">none</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
struts config file: struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- <constant name="struts.objectFactory" value="spring" /> -->
<constant name="struts.objectFactory"
value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<constant name="struts.devMode" value="false" />
<package name="swordlite" namespace="/" extends="struts-default">
<global-results>
<result name="myerror">/mrg/error.jsp</result>
<result name="re2Editpage">/mrg/re2Editpage.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="re2Editpage"
exception="org.hibernate.PropertyValueException"></exception-mapping>
</global-exception-mappings>
</package>
</struts>
was:
java.lang.ClassCastException: A action cannot be cast to B action when A chain
to B.
ChainingInterceptor.java has a bug in intercept function when Result type is
chain.
Intercept function of ChainingInterceptor will change action member of
DefaultActionInvocation class. And invokeAction of DefaultActionInvocation will
fail in line 450.
> Struts2 raise java.lang.ClassCastException when Result type is chain
> ---------------------------------------------------------------------
>
> Key: WW-4105
> URL: https://issues.apache.org/jira/browse/WW-4105
> Project: Struts 2
> Issue Type: Bug
> Components: Core Interceptors
> Affects Versions: 2.3.14.3
> Environment: tomcat6 struts2.3.*
> Reporter: zhouyong
> Fix For: 2.3.x
>
>
> java.lang.ClassCastException: A action cannot be cast to B action when A
> chain to B.
> ChainingInterceptor.java has a bug in intercept function when Result type is
> chain.
> Intercept function of ChainingInterceptor will change action member of
> DefaultActionInvocation class. And invokeAction of DefaultActionInvocation
> will fail in line 450.
> My action class has a annotation. It is
> org.springframework.transaction.annotation.Transactional. Action work good
> if it has not org.springframework.transaction.annotation.Transactional
> AtestAction.java:
> package demo.action;
> import org.apache.struts2.convention.annotation.Action;
> import org.apache.struts2.convention.annotation.ParentPackage;
> import org.apache.struts2.convention.annotation.Result;
> import org.apache.struts2.convention.annotation.Results;
> import org.springframework.context.annotation.Scope;
> import org.springframework.stereotype.Service;
> import org.springframework.transaction.annotation.Transactional;
> @Transactional
> @ParentPackage(value="swordlite")
> @Service("AtestAction")
> @Scope(value = "prototype")
> @Results( {
> @Result(name = "test", location = "testb", type = "chain",
> params = {
> "defineId", "${_defineId}",
> "rp", "${_resultPage}"}
> )
> })
> public class AtestAction {
> @Action(value = "/testa")
> public String run() throws Exception
> { return "test"; }
> }
> BtestAction.java:
> import org.apache.struts2.convention.annotation.Action;
> import org.apache.struts2.convention.annotation.ParentPackage;
> import org.apache.struts2.convention.annotation.Result;
> import org.apache.struts2.convention.annotation.Results;
> import org.springframework.context.annotation.Scope;
> import org.springframework.stereotype.Service;
> import org.springframework.transaction.annotation.Transactional;
> @Transactional
> @ParentPackage(value="swordlite")
> @Service("BtestAction")
> @Scope(value="prototype")
> @Results({
> @Result(name="ok", location="/ok.jsp", type="dispatcher"),
> })
> public class BtestAction {
> @Action(value = "/testb")
> public String run() throws Exception
> { return "ok"; }
> }
> request: http://localhost:8080/test/testa.action
> raise error: java.lang.ClassCastException: demo.action.AtestAction cannot be
> cast to demo.action.BtestAction
> spring config file: applicationContext.xml
> <?xml version="1.0" encoding="UTF-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:aop="http://www.springframework.org/schema/aop"
> xmlns:tx="http://www.springframework.org/schema/tx"
> xmlns:context="http://www.springframework.org/schema/context"
> xmlns:util="http://www.springframework.org/schema/util"
> xmlns="http://www.springframework.org/schema/p"
> xsi:schemaLocation="http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
> http://www.springframework.org/schema/aop
> http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
> http://www.springframework.org/schema/tx
> http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
> http://www.springframework.org/schema/context
> http://www.springframework.org/schema/context/spring-context-2.5.xsd
> http://www.springframework.org/schema/util
> http://www.springframework.org/schema/util/spring-util-2.5.xsd">
> <context:component-scan base-package="..action,.**.spring" />
> <context:annotation-config />
> <aop:aspectj-autoproxy proxy-target-class="true"/>
> <bean id="propertyConfigurer"
> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
> <property name="locations">
> <list>
> <value>WEB-INF/config/db.properties</value>
> <value>WEB-INF/config/hibernate.properties</value>
> </list>
> </property>
> </bean>
> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
> destroy-method="close">
> <property name="driverClass" value="${database.working.driver}"></property>
> <property name="jdbcUrl" value="${database.working.url}"></property>
> <property name="user" value="${database.working.user}"></property>
> <property name="password" value="${database.working.password}"></property>
> <property name="maxPoolSize" value="${database.working.poolsize}"></property>
> <property name="minPoolSize" value="1"></property>
> <property name="initialPoolSize" value="1"></property>
> <property name="maxIdleTime" value="20"></property>
> </bean>
> <bean id="sessionFactory"
> class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
> <property name="dataSource" ref="dataSource" />
> <property name="packagesToScan">
> <list>
> <value>.*.model</value>
> </list>
> </property>
> <property name="hibernateProperties">
> <props>
> <prop key="hibernate.dialect">${hibernate.dialect}</prop>
> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
> <prop key="hibernate.hbm2ddl.auto">none</prop>
> </props>
> </property>
> </bean>
> <bean id="transactionManager"
> class="org.springframework.orm.hibernate3.HibernateTransactionManager">
> <property name="sessionFactory" ref="sessionFactory"></property>
> </bean>
> <tx:annotation-driven transaction-manager="transactionManager" />
> </beans>
> struts config file: struts.xml
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE struts PUBLIC
> "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
> "http://struts.apache.org/dtds/struts-2.3.dtd">
> <struts>
> <!-- <constant name="struts.objectFactory" value="spring" /> -->
> <constant name="struts.objectFactory"
> value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
> <constant name="struts.devMode" value="false" />
> <package name="swordlite" namespace="/" extends="struts-default">
> <global-results>
> <result name="myerror">/mrg/error.jsp</result>
> <result name="re2Editpage">/mrg/re2Editpage.jsp</result>
> </global-results>
> <global-exception-mappings>
> <exception-mapping result="re2Editpage"
> exception="org.hibernate.PropertyValueException"></exception-mapping>
> </global-exception-mappings>
> </package>
> </struts>
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira