Another way to grant this to work is make the Action implement an interface that has the desired method. So,
... create an interface ... interface I1 { String find(); } ... in your Action class declaration ... class MyStrutsAction implements I1 extends ActionSupport { ... } WHY THIS SOLUTION SHOULD WORK: This $Proxy? class that you mention is a Proxy. Proxies are cute little classes generated at runtime, that are NOT subclasses of your original class, but implements ALL your class' interfaces. The Idea of proxies is to intercept calls to your original class methods (in this case, your Struts Action), and do something before or after the call (in this case, open an Hibernate Transaction when you call it). This is the foundation of the Spring AOP and transaction support. See the following code snippet: interface I1 { String find(); } ... class C1 implements I1{ String find () { ... } String otherThing() { ... } } ... Object obj = new C1(); Object obj2 = Proxy.newProxyInstance(C1.class.getClassLoader(), new Class[] { Foo.class }, handler); // this is a method that returns a proxied instance of C1 C1 var1 = (C1) obj; // WORKS; C1 is an instance of C1 var1 = (C1) obj2; //!!Don`t WORK!! ClassCastException, because obj2 is a PROXY // para C1, and not an instance of CLASS C1; I1 var2 = (I1) obj; // WORKS, because the class implements the interface I1; I1 var2 = (I1) obj2; //WORKS, because obj2 is a proxy to C1, and implements all C1 interfaces; If I try to invoke in obj2, a proxied C1 instance, the method "otherThing" by reflection, it won't work, because the "otherThing" is not implement in an interface; WHY THIS SOLUTION DOESN'T WORK WITH VANILLA SPRING 2: I've published an issue in the Spring site for a problem that arises: http://opensource.atlassian.com/projects/spring/browse/SPR-3126 I've patched my Spring 2 Framework installation and now I don't have this problem anymore. [ Sorry, I didn't published the patch on the Spring site because at the time I didn't know that Patches could be published :). Anyway, for the bold of you the link above shows the exact solution that I applied. ] Basically, Spring is actually doing, in an oversimplified, pseudo java, code, is this: C1 obj1 = new C1();//where C1 is your action class... Object obj2 = Proxy.newProxyInstance(C1.class.getClassLoader(), new Class[] { Foo.class }, handler); //that returns de $Proxy??? class; that's what proxies do; they return a class that //implement all of the objects interfaces; Method m = obj2.getClass().getMethod("find"); //a method from the $Proxy??? class; obj1.getClass().invoke(m, ...) ; //boom! the method doesn't belong to C1, but to the $Proxy???; Adam Ruggles <[EMAIL PROTECTED]> wrote on 06/03/2007 00:22:32: > I found the solution to this and I wanted to post it on the list. > > adding proxy-target-class="true" fixes it. > > <tx:annotation-driven transaction-manager="transactionManager" > proxy-target-class="true" /> > > Adam Ruggles wrote: > > Creating a service object seems to have worked. Now I'm going to have > > to re-think using action support. This project is not complicated > > enough to warrant another layer. > > > > Thanks for your help. > > > > Paul Benedict wrote: > >> Adam, > >> > >> I have never seen anyone attach Spring transactional logic to an > >> action, and called DAOs straight from the action. That's not good > >> practice, because it mashes web, business, and data layers all in one > >> place. > >> > >> I wouldn't blame struts here (yet). I'd first move your code into a > >> service object and then inject the service into the action. If there > >> really is a problem with Struts, then the problem will persist (pun > >> intended); but when you move them to the service layer, it will > >> indicate whether you have mis-configured Spring or if Struts is at > >> fault. > >> > >> Paul > >> > >> Adam Ruggles wrote: > >>> I am following the guide here > >>> http://cwiki.apache.org/S2WIKI/struts-2-spring-2-jpa-ajax.html > >>> > >>> For some reason when trying to map a method other than execute I > >>> recieve the following error: > >>> - Servlet.service() for servlet default threw exception > >>> java.lang.NoSuchMethodException: $Proxy18.find() > >>> > >>> Below are the configuration files and a segment of the UserAction > >>> class. > >>> > >>> 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.0.dtd"> > >>> <struts> > >>> <constant name="struts.objectFactory" value="spring" /> > >>> <!-- <constant name="struts.devMode" value="true" /> --> > >>> <include file="struts-default.xml"/> > >>> <package name="havoc" extends="struts-default"> > >>> <action name="list" class="userAction" method="execute"> > >>> <result name="success">/WEB-INF/pages/list.jsp</result> > >>> </action> > >>> <action name="save" class="userAction" method="save"> > >>> <result name="success" type="redirect">/list.action</result> > >>> </action> > >>> <action name="find" class="userAction" method="find"> > >>> <result name="success">/WEB-INF/pages/index.jsp</result> > >>> </action> > >>> </package> > >>> </struts> > >>> > >>> Application Context > >>> <?xml version="1.0" encoding="UTF-8"?> > >>> <beans default-autowire="byName" > >>> 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" > >>> > >>> xsi:schemaLocation="http://www.springframework.org/schema/beans > >>> http://www.springframework.org/schema/beans/spring-beans-2.0.xsd > >>> http://www.springframework.org/schema/aop > >>> http://www.springframework.org/schema/aop/spring-aop-2.0.xsd > >>> http://www.springframework.org/schema/tx > >>> http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> > >>> > >>> <bean id="propertyConfigurer" > >>> class="org.springframework.beans.factory.config. > PropertyPlaceholderConfigurer" > >>> autowire="no"> > >>> <property name="location" value="/WEB-INF/havoc.properties"/> > >>> </bean> > >>> > >>> <bean id="config" class="com.havoc.forum.util.Config" autowire="no"> > >>> <property name="location" value="/WEB-INF/havoc.properties"/> > >>> </bean> > >>> <bean id="dataSource" > >>> class="org.springframework.jdbc.datasource.DriverManagerDataSource"> > >>> <property name="driverClassName" > >>> value="${jdbc.driverClassName}"/> > >>> <property name="url" value="${jdbc.url}"/> > >>> <property name="username" value="${jdbc.username}"/> > >>> <property name="password" value="${jdbc.password}"/> > >>> </bean> > >>> <bean id="sessionFactory" > >>> class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> > >>> <property name="dataSource" ref="dataSource"/> > >>> <!-- This will cause spring to return the raw > SessionFactory >>> instead of the spring proxied one. --> > >>> <!-- <property name="exposeTransactionAwareSessionFactory" > >>> value="false" /> --> > >>> <property name="configurationClass" > >>> value="org.hibernate.cfg.AnnotationConfiguration"/> > >>> <property name="configLocation" > >>> value="classpath:hibernate.cfg.xml"/> <property > >>> name="hibernateProperties"> > >>> <props> > >>> <prop > >>> key="hibernate.dialect">${hibernate.dialect}</prop> > >>> <prop > >>> key="hibernate.cache.use_query_cache">${hibernate.cache. > use_query_cache}</prop> > >>> > >>> <prop > >>> key="hibernate.show_sql">${hibernate.show_sql}</prop> > >>> <prop > >>> key="hibernate.bytecode.use_reflection_optimizer">${hibernate. > bytecode.use_reflection_optimizer}</prop> > >>> > >>> <prop > >>> key="hibernate.cache.use_second_level_cache">${hibernate.cache. > use_second_level_cache}</prop> > >>> > >>> <prop > >>> key="hibernate.cache.provider_class">${hibernate.cache. > provider_class}</prop> > >>> > >>> <prop > >>> key="hibernate.current_session_context_class">thread</prop> > >>> <prop > >>> key="hibernate.transaction.factory_class">org.hibernate. > transaction.JDBCTransactionFactory</prop> > >>> > >>> </props> > >>> </property> </bean> > >>> <!-- >>> Instruct Spring to perform declarative > transaction management > >>> automatically > >>> on annotated classes. > >>> --> > >>> <tx:annotation-driven transaction-manager="transactionManager" /> > >>> <!-- Transaction manager for a single Hibernate >>> > SessionFactory (alternative to JTA) --> > >>> <bean id="transactionManager" > >>> class="org.springframework.orm.hibernate3.HibernateTransactionManager"> > >>> <property name="sessionFactory"><ref > >>> bean="sessionFactory"/></property> > >>> </bean> > >>> > >>> <!-- Model Objects --> > >>> <bean id="user" class="com.havoc.forum.model.User" /> > >>> <bean id="group" class="com.havoc.forum.model.Group" /> > >>> <bean id="rank" class="com.havoc.forum.model.Rank" /> > >>> > >>> <!-- Data Access Objects --> > >>> <bean id="userDAO" class="com.havoc.forum.dao.hibernate.UserDAO" /> > >>> <bean id="groupDAO" class="com.havoc.forum.dao.hibernate.GroupDAO" /> > >>> <bean id="rankDAO" class="com.havoc.forum.dao.hibernate.RankDAO" /> > >>> <!-- Actions --> > >>> <bean id="userAction" class="com.havoc.forum.action.UserAction" > >>> scope="prototype" /> > >>> </beans> > >>> > >>> UserAction > >>> > >>> public class UserAction extends ActionSupport { > >>> > >>> ... > >>> ... > >>> > >>> /** > >>> * Returns a user from the database or a new user. > >>> * @return SUCCESS or ERROR. > >>> * @throws Exception if an error occurs. > >>> */ > >>> @Transactional(readOnly = true, propagation = > >>> Propagation.REQUIRED, rollbackFor = PersistenceException.class) > >>> public String find() { > >>> if (user != null && user.getId() != null) { > >>> user = userDAO.find(user.getId()); > >>> return SUCCESS; > >>> } > >>> user = new User(); > >>> return SUCCESS; > >>> } > >>> > >>> > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: [EMAIL PROTECTED] > >> For additional commands, e-mail: [EMAIL PROTECTED] > >> > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] >