'Spring ProxyFactoryBean - Interceptor/Advice sometimes not called/missing

My Spring beans should be called like this:

myProxy -> myDynamicProxy -> myInterceptor -> myService

This works most of the time, but sometimes myInterceptor is skipped.

Code/Spring Configuration:

myProxy

Class (pseudo code)

public class MyProxy implements MyService {

    private final MyService target;

    public MyProxy(final MyService target) {
        this.target = target;
    }

    @Override
    public void someMethod() {
        target.someMethod();
    }
}

XML

<bean id="myProxy" class="com.mp5er.MyProxy">
    <constructor-arg ref="myDynamicProxy"/>
</bean>

myDynamicProxy

XML

<bean id="myDynamicProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces">
        <value>com.mp5er.MyService</value>
    </property>
    <property name="target">
        <ref bean="myServiceImpl" />
    </property>
    <property name="interceptorNames">
        <list>
            <idref bean="myInterceptor" />
        </list>
    </property>
</bean>

myInterceptor

XML

<bean id="myInterceptor"
      class="org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="accessDecisionManager" ref="myAccessDecisionManager" />
    <property name="objectDefinitionSource">
        <value>
            myValue
        </value>
    </property>
</bean>

Stacktrace (MethodSecurityInterceptor is called)

at com.mp5er.MyServiceImpl.someMethod(MyServiceImpl.java:256)
at jdk.internal.reflect.GeneratedMethodAccessor1905.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy240.someMethod(Unknown Source)
at com.mp5er.MyProxy.someMethod(MyProxy.java:91)

Stacktrace (MethodSecurityInterceptor is NOT called)

at com.mp5er.MyServiceImpl.someMethod(MyServiceImpl.java:256)
at jdk.internal.reflect.GeneratedMethodAccessor1956.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
at com.sun.proxy.$Proxy240.someMethod(Unknown Source)
at com.mp5er.MyProxy.someMethod(MyProxy.java:91)

I'm not able to debug the problem because it happens only on the build server. Somehow myDynamicProxy gets initialized without myInterceptor. The spring debug log shows, that ProxyFactoryBean#adviceChanged is not called after myInterceptor is initialized:

16:09:04,518 INFO  [net.sf.acegisecurity.intercept.AbstractSecurityInterceptor] Validated configuration attributes
16:09:04,518 DEBUG [org.springframework.aop.framework.ProxyFactoryBean] Advice has changed; re-caching singleton instance

Spring version is 5.1.15.RELEASE and the application is running on Tomcat 8 with OpenJDK 11.0.9.



Solution 1:[1]

It was a bug in Spring Framework and has been fixed in Spring 5.3.14

https://github.com/spring-projects/spring-framework/issues/12238

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mp5er