struts-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Yannick le Restif (JIRA)" <>
Subject [jira] Commented: (WW-3127) Autoware fails on proxied objects
Date Wed, 05 May 2010 13:25:02 GMT


Yannick le Restif commented on WW-3127:

Even if this discussion is getting a bit old now I thought it would still be of some use to
give you some answers on this :
- First and most important, **** The problem above does NOT appear when struts.objectFactory.spring.autoWire.alwaysRespect
option is set to true**** => that might be the reason you struts2 guys haven't had it +
this is for almost everybody (including us) the solution to the problem. Maybe also this option
should be set to "true" by default.
- ALL beans advised by Spring AOP, whether using JDK or CGLIB, will be proxied. BUT, beans
that are not advised won't be proxied (at least if no other postprocessor proxies them), even
if AOP is enabled.
- The problem happens when the above option is set to false because autowiring is done AFTER
bean postprocessing. What this means is that autowiring is done on the proxy rather than on
the class, which can't be done because proxy just doesn't have the fields !! I changed the
order of the lines in SpringObjectFactory and it worked.

This is the original code snippet (in com.opensymphony.xwork2.spring.SpringObjectFactory,
l. 146 to 170 in xwork 2.1.6) :
    public Object buildBean(Class clazz, Map<String, Object> extraContext) throws Exception
        Object bean;

        try {
            // Decide to follow autowire strategy or use the legacy approach which mixes injection
            if (alwaysRespectAutowireStrategy) {
                // Leave the creation up to Spring
                bean = autoWiringFactory.createBean(clazz, autowireStrategy, false);
                return injectInternalBeans(bean);
            } else {
                bean = autoWiringFactory.autowire(clazz, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR,
                bean = autoWiringFactory.applyBeanPostProcessorsBeforeInitialization(bean,
                // We don't need to call the init-method since one won't be registered.
                bean = autoWiringFactory.applyBeanPostProcessorsAfterInitialization(bean,
                return autoWireBean(bean, autoWiringFactory);
        } catch (UnsatisfiedDependencyException e) {
            if (LOG.isErrorEnabled())
                LOG.error("Error building bean", e);
            // Fall back
            return autoWireBean(super.buildBean(clazz, extraContext), autoWiringFactory);

So all I did was to change the last 2 lines before the catch :

                bean = autoWiringFactory.applyBeanPostProcessorsAfterInitialization(bean,
                return autoWireBean(bean, autoWiringFactory);

                //autowiring first
                bean = autoWireBean(bean, autoWiringFactory);
                //doing the post processing (this is where aop is performed)
                bean = autoWiringFactory.applyBeanPostProcessorsAfterInitialization(bean,
                return bean;

Hoping this will be of some use to someone !

> Autoware fails on proxied objects
> ---------------------------------
>                 Key: WW-3127
>                 URL:
>             Project: Struts 2
>          Issue Type: Bug
>          Components: Plugin - Spring
>    Affects Versions: 2.1.6
>            Reporter: Vasiliy Gagin
>             Fix For: Future
> com.opensymphony.xwork2.spring.SpringObjectFactory#buildBean method calls autoWiringFactory.applyBeanPostProcessorsAfterInitialization()
> In some cases this method can return a JDK Proxy instead of action. Following call to
autoWireBean method attempts to autowire proxy itself instead of the action.
> As a result the action remains "not-wired".
> May be autowiring should happen before applying post processors "AfterInitialization".

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message