Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProxyFactoryBean getObject called before setInterceptorNames, silently creating an invalid proxy [SPR-7582] #12238

Closed
spring-projects-issues opened this issue Sep 21, 2010 · 7 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Sep 21, 2010

nigel magnay opened SPR-7582 and commented

We have an application that uses a fairly standard pattern to declare a proxy for a bean:

    <bean id="AService" name="aService" class="org.springframework.aop.framework.ProxyFactoryBean">
    	<property name="target"><ref bean="AServiceTXN"/></property>
    	<property name="interceptorNames">
    		<list>
    		   <value>Interceptor1</value>
                           <value>Interceptor2</value>  
                            ...
                           <value>InterceptorN</value>
    		</list>
    	</property>
    </bean>

The instantiation order causes this bean to be being created in response to an unrelated autowiring request, e.g:

@Autowired(required=false)
List<SomeOther> someOthers;

Which is internally executing getBeanNamesForType().

This causes a chain of objects to be created, and the ProxyFactoryBean for AService to be called with getObject().

However, this getObject() call is in advance of Spring having set the interceptorNames. Thus the proxy is created, and the advisorChainInitialized variable set to true with no interceptor names.

There's several things here

  1. I don't see why spring is calling getObject on an uninitialized factory; it ought to have set the properties first. I don't believe there are circular dependencies here (since it is initiated by a request to find all instances of an unrelated class). I can remove the problem (for one bean, but this applies to many) by creating a derived type of ProxyFactoryBean that sets the target and interceptorNames on construction... but this seems to be a nasty workaround as I'd have to set it for many, many beans. If it believes there to be a circular dependency I'd expect an exception.
  2. If setInterceptorNames finds that advisorChainInitialized == true, it ought to throw an exception, since it is clearly too late to influence the interception chain (so for example security interceptors mysteriously fail to work).

Affects: 2.5.6

Attachments:

Referenced from: pull request #1477

2 votes, 3 watchers

@spring-projects-issues
Copy link
Collaborator Author

nigel magnay commented

I have tried this with Spring 3, and it's a problem there too.

In fact, there are also scenarios where ProxyFactoryBean is re-entered because of a loop (because of executing getBeanNamesForType(), not a real dependency loop), where you then end up with many multiples of the interceptors created.

@spring-projects-issues
Copy link
Collaborator Author

Alar Kvell commented

I can confirm this with Spring 2.0.8

I used a workaround: in afterPropertiesSet method, set advisorChainInitialized to false.

@spring-projects-issues spring-projects-issues added type: bug A general bug status: waiting-for-triage An issue we've not yet triaged or decided on in: core Issues in core modules (aop, beans, core, context, expression) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues removed the type: bug A general bug label Jan 11, 2019
@rstoyanchev rstoyanchev added status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 11, 2019
@spring-projects-issues
Copy link
Collaborator Author

Bulk closing outdated, unresolved issues. Please, reopen if still relevant.

@marijnm
Copy link

marijnm commented Nov 11, 2020

This is still an issue

@sbrannen
Copy link
Member

@marijnm, would you be willing to provide a simple example project that demonstrates the issue -- for example, if the form of a GitHub repository or ZIP file that we can download and use to reproduce the issue?

@sbrannen sbrannen added the status: waiting-for-feedback We need additional information before we can continue label Nov 12, 2020
@mp5er
Copy link

mp5er commented Feb 10, 2021

I'm facing the same problem. Detailed description: https://stackoverflow.com/questions/66133760/spring-proxyfactorybean-interceptor-advice-sometimes-not-called-missing

The ProxyFactoryBean also tries multiple times to create the Proxy while it's not initialized:

org.springframework.beans.factory.FactoryBeanNotInitializedException: Cannot determine target class for proxy
	at org.springframework.aop.framework.ProxyFactoryBean.getSingletonInstance(ProxyFactoryBean.java:322)
	at org.springframework.aop.framework.ProxyFactoryBean.getObject(ProxyFactoryBean.java:252)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:135)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1674)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1248)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:257)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:303)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:676)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:188)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1340)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1186)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:303)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1674)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1426)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
.....

After the first call of getObject the advisorChainInitialized is set to true and the adivces are not added.

Maybe advisorChainInitialized should be set to false here before throwing the exception.

Spring version: 5.1.15.RELEASE
OS: Linux
JDK: OpenJDK 11.0.9

@kennymacleod
Copy link

I'm seeing behaviour that looks very like this (i.e. getObject being called from within Spring before setInterceptorNames, and advisorChainInitialized being set to true and short-circuiting the logic), but I can't come up with anything simpler than what @mp5er provided.

I'm using Spring Framework 5.1.18.

@jhoeller jhoeller self-assigned this Dec 13, 2021
@jhoeller jhoeller added type: bug A general bug and removed status: waiting-for-feedback We need additional information before we can continue status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process labels Dec 13, 2021
@jhoeller jhoeller added this to the 5.3.14 milestone Dec 13, 2021
@jhoeller jhoeller reopened this Dec 13, 2021
@jhoeller jhoeller added the for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x label Dec 13, 2021
@jhoeller jhoeller added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x labels Dec 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

7 participants