Comments (6)
Thank you, @lukaszlenart !
Even when the java.lang.reflect.Method
references the interface's method (i.e. I#doSth()
), java.lang.reflect.Method#invoke()
will return the correct value depending on the first argument (i.e. the target instance).
It should be OK if the following test passes, right?
@Test
public void should() throws Exception {
Map defaultContext = new HashMap<>();
Map<String, Object> root = new HashMap<>();
root.put("a", new A());
root.put("b", new B());
assertTrue((Boolean) Ognl.getValue("a.doSth()", defaultContext, root));
assertFalse((Boolean) Ognl.getValue("b.doSth()", defaultContext, root));
}
Please let me know if I am misunderstanding the issue.
from ognl.
@harawata you are right, it's even clearer to call the public method in such case 👏
from ognl.
@Farbfetzen ,
Thank you for re-filing the issue.
@lukaszlenart ,
Here are some additional info.
The following test yields the "illegal reflective access" warning on Java 9+ and an exception on Java 16+ [1].
@Test
public void testMapContainsKey() throws Exception {
Map defaultContext = new HashMap<>();
Map<String, Object> root = new HashMap<>();
root.put("map", Collections.singletonMap("key", "value"));
assertTrue((Boolean) Ognl.getValue("map.containsKey('key')", defaultContext, root));
}
This happens because OGNL calls the containsKey()
method of the private class java.util.Collections$SingletonMap
.
The method OGNL should call is the one that is defined in java.util.Map
.
The comment on the relevant line seems to imply that this behavior is intentional, but can you think of a case where it is necessary (or more appropriate) to call "the most specific" method rather than the same method defined in the superclass/interface? (there seems to be no test case)
I'm working on a fix which basically alters the priority when choosing the method to call.
[1] Stack Trace
java.lang.reflect.InaccessibleObjectException: Unable to make public boolean java.util.Collections$SingletonMap.containsKey(java.lang.Object) accessible: module java.base does not "opens java.util" to unnamed module @11739fa6
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at ognl.AccessibleObjectHandlerPreJDK9.setAccessible(AccessibleObjectHandlerPreJDK9.java:58)
at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:1211)
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1962)
at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:2038)
at ognl.ASTMethod.getValueBody(ASTMethod.java:97)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.ASTChain.getValueBody(ASTChain.java:141)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.Ognl.getValue(Ognl.java:586)
at ognl.Ognl.getValue(Ognl.java:688)
at ognl.Ognl.getValue(Ognl.java:658)
at ognl_default_method.OgnlDefaultMethodTest.testMapContainsKey(OgnlDefaultMethodTest.java:97)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
from ognl.
Probably in case of interfaces it makes sense to call interface version, but I think we also need to cover the below case
interface I {
boolean doSth();
}
class A implements I {
public boolean doSth() { return true ; }
}
class B extends A {
public boolean doSth() { return false; }
}
from ognl.
I think you are right, but we can try to play with the scoring to score private methods lower - maybe that will solve the problem.
from ognl.
I found a case where calling subclass method is more appropriate.
@Test
public void shouldInvokeSyntheticBridgeMethod() throws Exception {
StringBuilder root = new StringBuilder("abc");
Assert.assertEquals((int) 'b',
Ognl.getValue("codePointAt(1)", defaultContext, root));
}
I had considered tweaking the score, but this comparison seems to make sense only when two methods have the same score and (almost) same signature.
So, for now, the plan is to use the public one over non-public one.
Please take a look at #144 when you have time.
from ognl.
Related Issues (20)
- IllegalArgumentException when calling Ognl.getValue(Object, Object, Class) HOT 1
- Should this null-check be here? HOT 2
- Varargs method not found if no varargs are given HOT 2
- Developer Guide uses deprecated code HOT 4
- The 3.2.18 version of ognl.Ognl#getValue(..) is not easy to use at all HOT 3
- "Two vararg methods with same score" for resteasy ClientWebTarget.request() HOT 13
- Move OGNL under a dedicated organisation HOT 10
- java.lang.ArithmeticException: / by zero HOT 3
- OGNL issues with java 16 and 17 HOT 9
- Struts2 2.5 and struts2-jquery-plugin HOT 2
- In 3.3.3 (and before) compileExpression fails without add-opens on Java 17 HOT 13
- 如何解决安全问题。How ognl solve safety problem HOT 5
- Ognl.createDefaultContext(Object, ClassResolver) throws "IllegalArgumentException" HOT 4
- method with varargs invoked result exception: java.lang.ArrayStoreException HOT 6
- Most unit tests no longer running? HOT 2
- Cannot call static method through interface? HOT 8
- Request for posting of Maven signing key(s) HOT 2
- Dependency Dashboard
- Ognl choosing method on unexported class rather than exported interface
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ognl.