commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "recyclebin5385 (JIRA)" <>
Subject [jira] [Created] (OGNL-238) OGNLRuntime doesn't handle parameterized method arguments correctly for a grandchild class of a generic class
Date Fri, 26 Jul 2013 13:39:48 GMT
recyclebin5385 created OGNL-238:

             Summary: OGNLRuntime doesn't handle parameterized method arguments correctly
for a grandchild class of a generic class
                 Key: OGNL-238
             Project: Commons OGNL
          Issue Type: Bug
          Components: Core Runtime
    Affects Versions: 3.0
         Environment: Windows 7 64bit, Java Runtime Environment 7
            Reporter: recyclebin5385

Suppose there are classes as described below.
Class Foo<T> is a generic class with a type parameter T.
It has a property named "x" whose type is T; Foo has methods "T getX()" and "void setX(T x)".
Class Bar is a direct derived class of Foo<Integer>.
Class Baz is a direct derived class of Bar and class Qux is a direct derived class of Baz.
In short, there is an inheritance tree like this: Foo<T> -> Bar -> Baz -> Qux.

Static method ognl.Ognl.setValue(String expression, Object root, Object value) has an ability
to resolve a type parameter of an argument of a method.
But it does not work well for a derived class of a generic class.

If you execute Ognl.setValue("tmp.x", root, "123") where "tmp" is an instance of class Bar,
"123" is converted to an Integer and tmp's property X is set to an Integer.
It is a natural behavior because Bar extends Foo<Integer> and tmp's property x should
be an Integer.

But, if tmp is an instance of class Baz or Qux, which are both derived classes of Bar, the
conversion is never performed and tmp's property X is set to String "123".
It seems that type parameter handling works only when the class is DIRECTLY derived from a
generic class.

Here is a test code.
You will need to add ognl-3.0.6.jar and javassist-3.11.0.GA.jar to the classpath in order
to execute the code. They are bundled in Struts2.3.15.1.

import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import ognl.Ognl;

class Foo<T> {

    private T m_x;

    public T getX() {
        return m_x;

    public void setX(T x) {
        m_x = x;

class Bar extends Foo<Integer> {

class Baz extends Bar {

class Qux extends Baz {

public class OgnlBugTest {

    public static void main(String[] args) {
        try {
            Map<String, Foo<?>> root = new LinkedHashMap<String, Foo<?>>();
            root.put("foo", new Foo<Short>());
            root.put("bar", new Bar());
            root.put("baz", new Baz());
            root.put("qux", new Qux());

            Ognl.setValue("foo.x", root, "1");
            Ognl.setValue("bar.x", root, "2");
            Ognl.setValue("baz.x", root, "3");
            Ognl.setValue("qux.x", root, "4");

            for (Entry<String, Foo<?>> entry : root.entrySet()) {
                System.out.println(MessageFormat.format("{0} = {1} ({2})", entry.getKey(),
entry.getValue().getX(), entry.getValue().getX().getClass()));
        } catch (Exception exception) {

This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see:

View raw message