Description
Hello Spring Team,
We are currently migrating a large legacy application from Java 1.6/Spring 3 to a modern stack. We have encountered a persistent NoSuchMethodException when a Struts 2 Action, which is proxied by Spring AOP, is invoked.
This issue seems to be a deep incompatibility that only occurs with this specific combination of modern frameworks.
Environment
Spring Framework: 6.1.10
Struts 2: 7.0.3 (with struts2-spring-plugin)
Java Version: 21 (Temurin 21.0.3)
Servlet Container: Apache Tomcat 10.1.34
Steps to Reproduce
A complete Minimal, Reproducible Example (MRE) is attached as a Maven project (mre-project.zip).
Unzip the attached project.
Build the project using mvn clean package.
Deploy the resulting mre-project.war to Tomcat 10.1.
Access the URL: http://localhost:8080/mre-project/test.action
Current Behavior
When the URL is accessed, the application fails with a java.lang.NoSuchMethodException. The Struts 2 DefaultActionInvocation is unable to find the execute() method on the Spring-generated CGLIB proxy class.
Here is the stack trace from the MRE:
java.lang.NoSuchMethodException: com.example.mre.TestAction$$SpringCGLIB$$0.execute()
ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1901)
ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
org.apache.struts2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:101)
org.apache.struts2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:93)
ognl.OgnlRuntime.callMethod(OgnlRuntime.java:2034)
ognl.ASTMethod.getValueBody(ASTMethod.java:97)
ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
ognl.SimpleNode.getValue(SimpleNode.java:258)
ognl.Ognl.getValue(Ognl.java:586)
org.apache.struts2.ognl.OgnlUtil.ognlGet(OgnlUtil.java:425)
org.apache.struts2.ognl.OgnlUtil.callMethod(OgnlUtil.java:401)
org.apache.struts2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:447)
org.apache.struts2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:320)
org.apache.struts2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:271)
... (stack trace continues)
Expected Behavior
The DefaultActionInvocation should successfully find and invoke the execute() method on the Spring-generated proxy, allowing the action to execute without error.
Additional Context
The issue occurs when AOP is enabled with proxy-target-class="true" in applicationContext.xml. We believe the CGLIB proxy generated in the Java 21 environment is not correctly exposing the methods of the target Action class to the OGNL runtime.
Thank you for your time and for maintaining this great framework. Please let us know if you need any further information.