4

I have this class hierarchy

StudentClass .java

public class StudentClass {

    private List<Student> studentList;

    public List<Student> getStudentList() {
        return studentList;
    }

    public void setStudentList(List<Student> studentList) {
        this.studentList = studentList;
    }
}

Student.java

public class Student {

    private Child child;

    private int   studAge;

    public Student(Child child, int studAge) {
        this.child = child;
        this.studAge = studAge;
    }

    public Child getChild() {
        return child;
    }

    public void setChild(Child child) {
        this.child = child;
    }

    public int getStudAge() {
        return studAge;
    }

    public void setStudAge(int studAge) {
        this.studAge = studAge;
    }

}

Child.java

public class Child {

    private String name;

    private int    age;

    public Child(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

Main class

Through some logic i build this expression to execute through MVEL. This piece of code works fine when child2 is null, but when child1 is null it gives below error. This is a valid scenario, and it is just a replica of my entities from my application. Child might come as null inside Parent.

Issue only comes when object is null at index 0 , rest all indexes it works fine, even if at index 1 it is null, and index 0 fails if condition, then it will execute at index 2

public class MvelTest {

    public static void main(String args[]) throws Exception {
        String s = "if(contextObjectStudentClass.?studentList != null ){ foreach ( loopVariable0 : contextObjectStudentClass.?studentList){if ( loopVariable0.?child.?age==21 ){return  loopVariable0.?child.?name ;}}}return null ;";

        Child child2 = new Child("ankur", 23);
        Child child1 = null;
        Child child3 = new Child("ankurs", 21);

        Student s1 = new Student(child1, 21);
        Student s2 = new Student(child2, 23);
        Student s3 = new Student(child3, 27);

        List<Student> studentList = new ArrayList<Student>();
        studentList.add(s1);
        studentList.add(s2);
        studentList.add(s3);

        StudentClass class1 = new StudentClass();
        class1.setStudentList(studentList);

        Map map = new HashMap();
        map.put("contextObjectStudentClass", class1);

        System.out.println(MVEL.eval(s, map));

    }
}

Exception

Exception in thread "main" java.lang.RuntimeException: cannot invoke getter: getChild (see trace)
    at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:70)
    at org.mvel2.optimizers.impl.refl.nodes.VariableAccessor.getValue(VariableAccessor.java:37)
    at org.mvel2.optimizers.dynamic.DynamicGetAccessor.getValue(DynamicGetAccessor.java:73)
    at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)
    at org.mvel2.ast.BinaryOperation.getReducedValueAccelerated(BinaryOperation.java:114)
    at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
    at org.mvel2.ast.IfNode.getReducedValueAccelerated(IfNode.java:73)
    at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
    at org.mvel2.ast.ForEachNode.getReducedValue(ForEachNode.java:136)
    at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:106)
    at org.mvel2.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:49)
    at org.mvel2.MVEL.eval(MVEL.java:408)
    at org.mvel2.ast.IfNode.getReducedValue(IfNode.java:89)
    at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:106)
    at org.mvel2.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:49)
    at org.mvel2.MVEL.eval(MVEL.java:165)
    at com.nucleus.rules.service.MvelTest.main(MvelTest.java:34)
Caused by: java.lang.NullPointerException
    at org.mvel2.optimizers.impl.refl.nodes.NullSafe$1.getValue(NullSafe.java:39)
    at org.mvel2.optimizers.impl.refl.nodes.NullSafe.getValue(NullSafe.java:54)
    at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:40)
    ... 16 more
Aleksandr M
  • 23,647
  • 12
  • 63
  • 129
Ankur Singhal
  • 23,626
  • 10
  • 70
  • 108
  • The exception is odd in that does not seem to reference what I would think it would, but you are doing `loopVariable0.?child.?age` which would be invoked even if the child is null which would cause that NPE. – mkobit Nov 10 '14 at 09:14
  • @MikeKobit yes but somehow it hold first element in some node and compares, might be. since adding null object on 2nd index inside list, does not cause any issue, even if first element does not meet criteria, 3rd element gets executed. – Ankur Singhal Nov 10 '14 at 09:20
  • Can you please tell Mvel version no. – Siva Kumar Dec 11 '14 at 21:06

1 Answers1

0

Its work for me in version 2.0. I have tried even null in 2 or 3 position its throwing exception

I have attached exception

    Exception in thread "main" [Error: cannot invoke getter: getChild [declr.class: Student; act.class: Student]]
[Near : {... ame ;}}} else { return "Noo" } ....}]
[Line: 1, Column: 218]
    at org.mvel.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:156)
    at org.mvel.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:54)
    at org.mvel.MVEL.eval(MVEL.java:124)
    at MvelTest.main(MvelTest.java:33)
Caused by: [Error: cannot invoke getter: getChild [declr.class: Student; act.class: Student]]
[Near : {... loopVariable0.?child.?name ;} ....}]
[Line: 1, Column: 143]
    at org.mvel.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:156)
    at org.mvel.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:54)
    at org.mvel.MVEL.eval(MVEL.java:107)
    at org.mvel.ast.IfNode.getReducedValue(IfNode.java:64)
    at org.mvel.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:106)
    ... 3 more
Caused by: [Error: cannot invoke getter: getChild [declr.class: Student; act.class: Student]]
[Near : {... Unknown ....}]
    at org.mvel.optimizers.impl.refl.GetterAccessor.getValue(GetterAccessor.java:51)
    at org.mvel.optimizers.impl.refl.VariableAccessor.getValue(VariableAccessor.java:38)
    at org.mvel.optimizers.dynamic.DynamicGetAccessor.getValue(DynamicGetAccessor.java:44)
    at org.mvel.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:97)
    at org.mvel.ast.BinaryOperation.getReducedValueAccelerated(BinaryOperation.java:64)
    at org.mvel.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:46)
    at org.mvel.ast.IfNode.getReducedValueAccelerated(IfNode.java:48)
    at org.mvel.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:46)
    at org.mvel.ast.ForEachNode.getReducedValue(ForEachNode.java:148)
    at org.mvel.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:106)
    ... 7 more
Caused by: [Error: cannot invoke getter: getAge [declr.class: Child; act.class: null]]
[Near : {... Unknown ....}]
    at org.mvel.optimizers.impl.refl.GetterAccessor.getValue(GetterAccessor.java:51)
    at org.mvel.optimizers.impl.refl.GetterAccessor.getValue(GetterAccessor.java:38)
    ... 16 more
Caused by: java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.mvel.optimizers.impl.refl.GetterAccessor.getValue(GetterAccessor.java:41)
    ... 17 more
Siva Kumar
  • 1,990
  • 1
  • 12
  • 26