NoSuchMethodException, генерируемый AnnotationValidationInterceptor при выполнении действия - PullRequest
0 голосов
/ 29 апреля 2011

Детали используемых банок: Struts2 2.2.1 Весна 3.0.5. ВЫПУСК Hibernate 3.6.0.FINAL

Я испытываю странную проблему при попытке выполнить действие, отображаемое следующим образом:

<action name="supplierSearch" class="supplierSearchAction">
            <result>/pages/suppliersearch.jsp</result>
</action>
<action name="searchForSupplier" class="supplierSearchAction" method="doSearch">
<result>/pages/suppliersearch.jsp</result>
</action>

первое действие отправляет пользователя на страницу поиска, он вводит строку поиска, а затем второе действие вызывается при публикации формы.

Действие в конфигурации весны выглядит следующим образом:

<bean id="supplierSearchAction"
    class="com.blah.SupplierSearchAction"
    scope="prototype">
    <property name="searchService" ref="supplierSearchService"></property>
</bean>

служба поиска использует поиск в режиме гибернации и определяется следующим образом:

<bean id="supplierSearchService"
        class="com.devcentre.yubi.application.service.SupplierSearchServiceImpl">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

Я использую Spring AOP для настройки границ моей транзакции, и постоянство конфигурации выглядит следующим образом:

<tx:annotation-driven transaction-manager="txManager" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                // annotated classes here
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">upgrade</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.provider_class">
                    net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
                <prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider
                </prop>
                <prop key="hibernate.search.default.indexBase">/lucene/indexes</prop>
                <prop key="hibernate.search.default.batch.merge_factor">10</prop>
                <prop key="hibernate.search.default.batch.max_buffered_docs">10</prop>
            </props>
        </property>

    </bean>

    <bean id="txManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

Spring настроен следующим образом в моем web.xml:

<listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/src/spring-config.xml 
            /WEB-INF/src/persistence-config.xml 
        </param-value>
    </context-param>

На странице поиска JSP у меня есть форма, которая отправляет строку поиска в действие, которое должно вызывать метод doSearch. Однако, когда я отправляю поиск, я получаю следующее исключение (потому что включен devmode):

Struts has detected an unhandled exception:

Messages:    $Proxy28.doSearch()
File:   java/lang/Class.java Line
number: 1,605

и затем трассировка стека:

java.lang.NoSuchMethodException: $Proxy28.addComponent()
    java.lang.Class.getMethod(Class.java:1605)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.getActionMethod(AnnotationValidationInterceptor.java:75)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:47)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)

Это очень странно, потому что в классе действия есть метод с подписью:

public String doSearch()

Может кто-нибудь помочь пролить свет на то, почему у ActionProxy нет ожидаемого метода?

Спасибо

Alex

Ответы [ 2 ]

1 голос
/ 30 апреля 2011

java.lang.NoSuchMethodException: $Proxy25.doSearch()

Обратите внимание, что имя вашего класса действий: $ Proxy25 .Похоже, что-то создает динамический прокси для вашего класса действий.Обычно это видно при использовании перехватчиков методов с использованием аспектно-ориентированного программирования (AOP) в методах класса - например, для таких вещей, как транзакции.

Например, время от времени я использую Google Guice и при использовании AOPПерехватчики методов в методах класса, действие с именем LoginAction будет иметь динамический прокси, созданный с именем LoginAction$$EnhancerByGuice$$someAdditionalCharacters. Хотя этот динамический прокси-сервер подклассифицирует методы класса, он не наследует аннотации. Я предполагаю, что здесь происходит то же самое.

Я не использую Spring, поэтому яне знаком с тем, какие библиотеки он использует для создания динамических прокси.

Обновление

Если вы удалите аннотации AOP из своего класса действий, тогда он должен работать как положено.Ваш класс действий может делегироваться классу сервисного уровня для обработки сохраняющегося в базе данных (вы можете поместить аннотацию @Transactional в метод (ы) этого класса).

0 голосов
/ 15 июня 2011

Похоже, что интеграция пружин и аннотаций struts2 все еще имеет свои преимущества ...

первого вызова getMethod из AnnotationValidationInterceptor можно избежать с помощью параметров исключения.

            <interceptor-ref name="validation">
                <param name="excludeMethods">YOURMETHODHERE</param>
            </interceptor-ref>

однако, это просто откладывает проблему до тех пор, пока метод DefaultActionInvocation не вызовет фактический метод, заканчивающийся в том же месте кода (getMethod Class # 1597), который завершается ошибкой с указанным именем метода на прокси.

1008 * Временное решение *

Единственный найденный мной функциональный обходной путь - использовать стандартный метод execute () для действия и разделить действия на различные классы.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...