[ 
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

Reply via email to