[ 
https://issues.apache.org/jira/browse/SYNCOPE-1635?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmitriy Brashevets updated SYNCOPE-1635:
----------------------------------------
    Description: 
Class org.apache.syncope.core.spring.ImplementationManager registers singleton 
bean for Rules that contains Configuration. Example of rule class 
org.apache.syncope.core.spring.policy.DefaultPasswordRule, example of 
confugration class that may contain the rule: 
org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf.

There is only one spring bean of rule of a particular type in the Spring 
Application Context.
Issue 1: The registration of singleton bean contains the concurrent issue: if 
the singletone is already registered further creation of the prototype scoped 
bean of the same class throws exception like:

{noformat}
org.springframework.beans.factory.BeanCreationException: Error creating bean 
with name 'ch.usp.syncope.core.persistence.jpa.dao.UspPasswordRule': Injection 
of autowired dependencies failed; nested exception is 
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 
'${beanName}' available
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:382)
    at 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
    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.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
    at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.zeroturnaround.javarebel.ix.invokeMethod(SourceFile:288)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildJavaWithConf(ImplementationManager.java:240)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildPasswordRule(ImplementationManager.java:112)
    at 
ch.usp.syncope.wrapper.ImplementationManagerWrapper.buildPasswordRule(ImplementationManagerWrapper.java:25)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.getPasswordLifeTime(ExecLogic.java:89)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.execute(ExecLogic.java:57)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$FastClassBySpringCGLIB$$1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at 
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
    at 
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at 
org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptor.invoke(DomainTransactionInterceptor.java:69)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$EnhancerBySpringCGLIB$$1.execute(<generated>)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.lambda$call$0(ExecEImpl.java:23)
    at 
org.apache.syncope.core.spring.security.AuthContextUtils.execWithAuthContext(AuthContextUtils.java:117)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:21)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:8)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No 
bean named 'ch.usp.syncope.core.persistence.jpa.dao.UspPasswordRule' available
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:779)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1008)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:556)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$000(AutowiredAnnotationBeanPostProcessor.java:118)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
    at 
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
    ... 31 more

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 
'${beanName}' available
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:779)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1008)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:556)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$000(AutowiredAnnotationBeanPostProcessor.java:118)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
    at 
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
    at 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
    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.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
    at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.zeroturnaround.javarebel.ix.invokeMethod(SourceFile:288)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildJavaWithConf(ImplementationManager.java:240)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildPasswordRule(ImplementationManager.java:112)
    at 
ch.usp.syncope.wrapper.ImplementationManagerWrapper.buildPasswordRule(ImplementationManagerWrapper.java:25)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.getPasswordLifeTime(ExecLogic.java:89)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.execute(ExecLogic.java:57)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$FastClassBySpringCGLIB$$1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at 
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
    at 
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at 
org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptor.invoke(DomainTransactionInterceptor.java:69)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$EnhancerBySpringCGLIB$$1.execute(<generated>)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.lambda$call$0(ExecEImpl.java:23)
    at 
org.apache.syncope.core.spring.security.AuthContextUtils.execWithAuthContext(AuthContextUtils.java:117)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:21)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:8)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
{noformat}
This may happen when two threads are trying to register singleton bean in 
Spring Application Context concurrently and at the same time. Thus, the 
org.apache.syncope.core.spring.ImplementationManager#buildJavaWithConf requires 
additional synchronization.


Issue 2: Moreover, the rule that is registered as a singleton bean has a state 
that can be changed. And if there're more than one domain with the same rule 
type but a different configuration for this rule -> then wrong logic can be 
executed in runtime as a wrong configuration can be used for this domain.
To solve this issue I see that for each domain the singleton bean should exist




 


  was:
Class org.apache.syncope.core.spring.ImplementationManager registers singleton 
bean for Rules that contains Configuration. Example of rule class 
org.apache.syncope.core.spring.policy.DefaultPasswordRule, example of 
confugration class that may contain the rule: 
org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf.

There is only one spring bean of rule of a particular type in the Spring 
Application Context.
Issue 1: The registration of singletone bean contains the concurrent issue: if 
the singletone is already registered further creation of the prototype scoped 
bean of the same class throws exception like:

{noformat}
org.springframework.beans.factory.BeanCreationException: Error creating bean 
with name 'ch.usp.syncope.core.persistence.jpa.dao.UspPasswordRule': Injection 
of autowired dependencies failed; nested exception is 
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 
'${beanName}' available
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:382)
    at 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
    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.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
    at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.zeroturnaround.javarebel.ix.invokeMethod(SourceFile:288)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildJavaWithConf(ImplementationManager.java:240)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildPasswordRule(ImplementationManager.java:112)
    at 
ch.usp.syncope.wrapper.ImplementationManagerWrapper.buildPasswordRule(ImplementationManagerWrapper.java:25)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.getPasswordLifeTime(ExecLogic.java:89)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.execute(ExecLogic.java:57)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$FastClassBySpringCGLIB$$1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at 
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
    at 
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at 
org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptor.invoke(DomainTransactionInterceptor.java:69)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$EnhancerBySpringCGLIB$$1.execute(<generated>)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.lambda$call$0(ExecEImpl.java:23)
    at 
org.apache.syncope.core.spring.security.AuthContextUtils.execWithAuthContext(AuthContextUtils.java:117)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:21)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:8)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No 
bean named 'ch.usp.syncope.core.persistence.jpa.dao.UspPasswordRule' available
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:779)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1008)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:556)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$000(AutowiredAnnotationBeanPostProcessor.java:118)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
    at 
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
    ... 31 more

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 
'${beanName}' available
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:779)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1008)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214)
    at 
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:556)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$000(AutowiredAnnotationBeanPostProcessor.java:118)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
    at 
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
    at 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
    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.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
    at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.zeroturnaround.javarebel.ix.invokeMethod(SourceFile:288)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildJavaWithConf(ImplementationManager.java:240)
    at 
org.apache.syncope.core.spring.ImplementationManager.buildPasswordRule(ImplementationManager.java:112)
    at 
ch.usp.syncope.wrapper.ImplementationManagerWrapper.buildPasswordRule(ImplementationManagerWrapper.java:25)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.getPasswordLifeTime(ExecLogic.java:89)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic.execute(ExecLogic.java:57)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$FastClassBySpringCGLIB$$1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at 
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
    at 
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at 
org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptor.invoke(DomainTransactionInterceptor.java:69)
    at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecLogic$$EnhancerBySpringCGLIB$$1.execute(<generated>)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.lambda$call$0(ExecEImpl.java:23)
    at 
org.apache.syncope.core.spring.security.AuthContextUtils.execWithAuthContext(AuthContextUtils.java:117)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:21)
    at 
ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:8)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
{noformat}
This may happen when two threads are trying to register singleton bean in 
Spring Application Context concurrently and at the same time. Thus, the 
org.apache.syncope.core.spring.ImplementationManager#buildJavaWithConf requires 
additional synchronization.


Issue 2: Moreover, the rule that is registered as a singleton bean has a state 
that can be changed. And if there're more than one domain with the same rule 
type but a different configuration for this rule -> then wrong logic can be 
executed in runtime as a wrong configuration can be used for this domain.
To solve this issue I see that for each domain the singleton bean should exist




 



> Create Rules with configurations for each domain, make creation thread safe
> ---------------------------------------------------------------------------
>
>                 Key: SYNCOPE-1635
>                 URL: https://issues.apache.org/jira/browse/SYNCOPE-1635
>             Project: Syncope
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 2.1.6, 2.1.9
>            Reporter: Dmitriy Brashevets
>            Priority: Major
>
> Class org.apache.syncope.core.spring.ImplementationManager registers 
> singleton bean for Rules that contains Configuration. Example of rule class 
> org.apache.syncope.core.spring.policy.DefaultPasswordRule, example of 
> confugration class that may contain the rule: 
> org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf.
> There is only one spring bean of rule of a particular type in the Spring 
> Application Context.
> Issue 1: The registration of singleton bean contains the concurrent issue: if 
> the singletone is already registered further creation of the prototype scoped 
> bean of the same class throws exception like:
> {noformat}
> org.springframework.beans.factory.BeanCreationException: Error creating bean 
> with name 'ch.usp.syncope.core.persistence.jpa.dao.UspPasswordRule': 
> Injection of autowired dependencies failed; nested exception is 
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean 
> named '${beanName}' available
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:382)
>     at 
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
>     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.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
>     at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
>     at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>     at java.lang.reflect.Method.invoke(Method.java:498)
>     at com.zeroturnaround.javarebel.ix.invokeMethod(SourceFile:288)
>     at 
> org.apache.syncope.core.spring.ImplementationManager.buildJavaWithConf(ImplementationManager.java:240)
>     at 
> org.apache.syncope.core.spring.ImplementationManager.buildPasswordRule(ImplementationManager.java:112)
>     at 
> ch.usp.syncope.wrapper.ImplementationManagerWrapper.buildPasswordRule(ImplementationManagerWrapper.java:25)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic.getPasswordLifeTime(ExecLogic.java:89)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic.execute(ExecLogic.java:57)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic$$FastClassBySpringCGLIB$$1.invoke(<generated>)
>     at 
> org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
>     at 
> org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752)
>     at 
> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
>     at 
> org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
>     at 
> org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
>     at 
> org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptor.invoke(DomainTransactionInterceptor.java:69)
>     at 
> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
>     at 
> org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic$$EnhancerBySpringCGLIB$$1.execute(<generated>)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecEImpl.lambda$call$0(ExecEImpl.java:23)
>     at 
> org.apache.syncope.core.spring.security.AuthContextUtils.execWithAuthContext(AuthContextUtils.java:117)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:21)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:8)
>     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
>     at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
>     at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
>     at java.lang.Thread.run(Thread.java:748)
> Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
> No bean named 'ch.usp.syncope.core.persistence.jpa.dao.UspPasswordRule' 
> available
>     at 
> org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:779)
>     at 
> org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
>     at 
> org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1008)
>     at 
> org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214)
>     at 
> org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:556)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$000(AutowiredAnnotationBeanPostProcessor.java:118)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
>     at 
> org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
>     ... 31 more
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean 
> named '${beanName}' available
>     at 
> org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:779)
>     at 
> org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
>     at 
> org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1008)
>     at 
> org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214)
>     at 
> org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:556)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$000(AutowiredAnnotationBeanPostProcessor.java:118)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
>     at 
> org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
>     at 
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
>     at 
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
>     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.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
>     at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
>     at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>     at java.lang.reflect.Method.invoke(Method.java:498)
>     at com.zeroturnaround.javarebel.ix.invokeMethod(SourceFile:288)
>     at 
> org.apache.syncope.core.spring.ImplementationManager.buildJavaWithConf(ImplementationManager.java:240)
>     at 
> org.apache.syncope.core.spring.ImplementationManager.buildPasswordRule(ImplementationManager.java:112)
>     at 
> ch.usp.syncope.wrapper.ImplementationManagerWrapper.buildPasswordRule(ImplementationManagerWrapper.java:25)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic.getPasswordLifeTime(ExecLogic.java:89)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic.execute(ExecLogic.java:57)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic$$FastClassBySpringCGLIB$$1.invoke(<generated>)
>     at 
> org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
>     at 
> org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752)
>     at 
> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
>     at 
> org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
>     at 
> org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
>     at 
> org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptor.invoke(DomainTransactionInterceptor.java:69)
>     at 
> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
>     at 
> org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecLogic$$EnhancerBySpringCGLIB$$1.execute(<generated>)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecEImpl.lambda$call$0(ExecEImpl.java:23)
>     at 
> org.apache.syncope.core.spring.security.AuthContextUtils.execWithAuthContext(AuthContextUtils.java:117)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:21)
>     at 
> ch.usp.syncope.core.provisioning.java.job.ExecEImpl.call(ExecEImpl.java:8)
>     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
>     at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
>     at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
>     at java.lang.Thread.run(Thread.java:748)
> {noformat}
> This may happen when two threads are trying to register singleton bean in 
> Spring Application Context concurrently and at the same time. Thus, the 
> org.apache.syncope.core.spring.ImplementationManager#buildJavaWithConf 
> requires additional synchronization.
> Issue 2: Moreover, the rule that is registered as a singleton bean has a 
> state that can be changed. And if there're more than one domain with the same 
> rule type but a different configuration for this rule -> then wrong logic can 
> be executed in runtime as a wrong configuration can be used for this domain.
> To solve this issue I see that for each domain the singleton bean should exist
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to