-
-
Notifications
You must be signed in to change notification settings - Fork 87
Description
@lukaszlenart Thank you for providing a patch for #390 in the 3.4.8 release. I have tested the new release, but unfortunately the issue I encountered still persists. I may have misdiagnosed it when I created my original post. Meanwhile some time has freed up so I was able to create a minimal example, that might provide more insight into the issue.
The following sample provides an exists() method on java.util.List, that takes a lambda expression. I've defined a property test that contains a value, which I want to check if it is present in the list. That property is defined in the root. Up to OGNL version 3.4.4 this returns true as expected. From 3.4.5 onward, it throws an exception ognl.NoSuchPropertyException: java.lang.String.test, which seems to be because it tries to evaluate test as a property of the list item. So #this == #root in that case, instead of the map that was set as root for the context.
package com.example;
import ognl.*;
import java.util.List;
import java.util.Map;
public class OgnlSample {
public static void main(String[] args) throws OgnlException {
OgnlRuntime.setMethodAccessor(List.class, new ObjectMethodAccessor() {
@Override
public Object callMethod(OgnlContext context, Object target, String methodName, Object[] args) throws MethodFailedException {
List<?> list = (List<?>) target;
if (methodName.equals("exists")) {
return exists(context, list, args);
}
return super.callMethod(context, target, methodName, args);
}
private static Object exists(OgnlContext context, List<?> list, Object[] args) {
return list.stream()
.anyMatch(item -> {
try {
Object value = Ognl.getValue(args[0], context, item);
if (!(value instanceof Boolean)) {
throw new RuntimeException("Lambda did not return boolean, returned '" + value + "' instead");
}
return (Boolean) value;
} catch (OgnlException e) {
throw new RuntimeException(e);
}
});
}
});
OgnlContext defaultContext = Ognl.createDefaultContext(Map.of(), null, null);
defaultContext.setRoot(Map.of(
"test", "value"
));
Object value = Ognl.getValue("myList.exists(:[ #this.equals(test) ])", defaultContext, Map.of(
"myList", List.of("value")
));
System.out.println(value);
}
}