Search code examples
javatomcatstruts2nosuchmethoderrorognl

java.lang.NoSuchMethodError for Ognl.createDefaultContext() in Struts 6.4.0


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:

  • Struts 2 version: 6.4.0
  • OGNL version: 3.3.4
  • Tomcat version: 9.0.82
  • Java version: 11

Steps Taken:

  1. Checked OGNL version compatibility: Ensured that the OGNL version matches the expected version in the Struts 2 dependencies.
  2. Reviewed method signatures in OGNL: Confirmed that the createDefaultContext method signature does not align with the call in OgnlValueStack.
  3. Verified Maven build: My application compiles successfully with Maven.
  4. Ran the application on Tomcat: The error appears when I run my artifacts with Tomcat.

Questions:

  • Is there a mismatch between the versions of Struts 2 and OGNL that I'm using?
  • Has anyone encountered a similar issue with Ognl.createDefaultContext?
  • Are there any known issues or solutions for this error with Struts 2 and OGNL?

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.

Solution

  • 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.