I'm encountering a java.lang.NoSuchMethodError
in my Java application using Struts 2 (v6.4.0) when trying to initialize the OgnlValueStack
. The error message is as follows:
java.lang.NoSuchMethodError: 'java.util.Map ognl.Ognl.createDefaultContext(java.lang.Object, ognl.MemberAccess, ognl.ClassResolver, ognl.TypeConverter)'
at com.opensymphony.xwork2.ognl.OgnlValueStack.setRoot(OgnlValueStack.java:151)
at com.opensymphony.xwork2.ognl.OgnlValueStack.<init>(OgnlValueStack.java:89)
at com.opensymphony.xwork2.ognl.OgnlValueStackFactory.createValueStack(OgnlValueStackFactory.java:86)
at com.opensymphony.xwork2.ognl.OgnlValueStackFactory.createValueStack(OgnlValueStackFactory.java:76)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.setContext(DefaultConfiguration.java:329)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:295)
at com.opensymphony.xwork2.config.ConfigurationManager.reload(ConfigurationManager.java:227)
at com.opensymphony.xwork2.config.ConfigurationManager.initialiseConfiguration(ConfigurationManager.java:84)
at com.opensymphony.xwork2.config.ConfigurationManager.wasConfigInitialised(ConfigurationManager.java:72)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:61)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:1124)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:625)
at org.apache.struts2.dispatcher.InitOperations.initDispatcher(InitOperations.java:48)
at org.apache.struts2.dispatcher.listener.StrutsListener.contextInitialized(StrutsListener.java:43)
...
Issue Details:
I've traced the issue to the setRoot
method in OgnlValueStack
, which calls Ognl.createDefaultContext
with the following parameters:
this.context = Ognl.createDefaultContext(this.root, securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter));
However, when I looked into the Ognl.java
class in OGNL, the createDefaultContext
function does not seem to have a matching method signature:
public static Map createDefaultContext(Object root, ClassResolver classResolver,
TypeConverter converter, MemberAccess memberAccess)
{
return addDefaultContext(root, classResolver, converter, memberAccess, new OgnlContext());
}
Project Setup:
Steps Taken:
createDefaultContext
method signature does not align with the call in OgnlValueStack
.Questions:
Ognl.createDefaultContext
?Any help or suggestions would be greatly appreciated. Thank you!
Edit:
Upon further investigation, I have verified that the types in the createDefaultContext
function used in Struts are correct. The method signature in Struts matches the expected parameters:
this.context = Ognl.createDefaultContext(this.root, securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter));
this.root
: Expected type is Object
.accessor
: Expected type is ClassResolver
(and RootAccessor extends
ClassResolver`).new OgnlTypeConverterWrapper(xworkConverter)
: Expected type is TypeConverter
.securityMemberAccess
: Expected type is MemberAccess
.The current version of Ognl
has a method with signature missing in the code:
public static OgnlContext createDefaultContext(Object root, MemberAccess memberAccess, ClassResolver classResolver, TypeConverter converter) { return addDefaultContext(root, memberAccess, classResolver, converter, null); }
Only the problem the method returns OgnlContext
instead of Map
. It reminds me an incompatibility problem with new version of Ognl 3.4.2 is on the classpath.
The version of struts2-core 6.4.0 has dependency on ognl 3.3.4. You should use this version.