Last active
November 2, 2019 08:46
-
-
Save harawata/ba122c27106802b34f84bcb8a6566932 to your computer and use it in GitHub Desktop.
Demo app trying to reproduce https://github.com/mybatis/mybatis-3/issues/1648 but to no avail.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ognl.*; | |
import java.util.*; | |
import java.util.concurrent.ConcurrentHashMap; | |
import java.lang.reflect.*; | |
public class ConcurrentGetValue { | |
public static void main(String[] args) { | |
int size = Integer.valueOf(args[0]); | |
final Person p = new Person(); | |
final Map<String, Object> map = new HashMap<String, Object>(); | |
map.put("person", p); | |
for (int i = 0; i < size; i++) { | |
new MyThread(map).start(); | |
} | |
} | |
public static class MyThread extends Thread { | |
private static final OgnlMemberAccess MEMBER_ACCESS = new OgnlMemberAccess(); | |
private static final OgnlClassResolver CLASS_RESOLVER = new OgnlClassResolver(); | |
private static final Map<String, Object> expressionCache = new ConcurrentHashMap<>(); | |
private final Map<String, Object> map; | |
private final OgnlContext ctxt; | |
public MyThread(Map<String, Object> map) { | |
this.map = map; | |
this.ctxt = (OgnlContext)Ognl.createDefaultContext(null, MEMBER_ACCESS, CLASS_RESOLVER, null); | |
} | |
public void run() { | |
try { | |
Boolean result = (Boolean)Ognl.getValue("person.pet.id != null", ctxt, map); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
public static interface HasId<T> { | |
T getId(); | |
} | |
public static class Person implements HasId<Integer> { | |
private Pet pet = new Pet(); | |
public Integer getId() { | |
return Integer.valueOf(123); | |
} | |
public Pet getPet() { | |
return pet; | |
} | |
} | |
public static class Pet { | |
public Integer getId() { | |
return Integer.valueOf(123); | |
} | |
} | |
public static class OgnlClassResolver extends DefaultClassResolver { | |
@Override | |
protected Class toClassForName(String className) throws ClassNotFoundException { | |
return Class.forName(className); | |
} | |
} | |
public static class OgnlMemberAccess implements MemberAccess { | |
private final boolean canControlMemberAccessible; | |
OgnlMemberAccess() { | |
this.canControlMemberAccessible = canControlMemberAccessible(); | |
} | |
@Override | |
public Object setup(Map context, Object target, Member member, String propertyName) { | |
Object result = null; | |
if (isAccessible(context, target, member, propertyName)) { | |
AccessibleObject accessible = (AccessibleObject) member; | |
if (!accessible.isAccessible()) { | |
result = Boolean.FALSE; | |
accessible.setAccessible(true); | |
} | |
} | |
return result; | |
} | |
@Override | |
public void restore(Map context, Object target, Member member, String propertyName, | |
Object state) { | |
if (state != null) { | |
((AccessibleObject) member).setAccessible((Boolean) state); | |
} | |
} | |
@Override | |
public boolean isAccessible(Map context, Object target, Member member, String propertyName) { | |
return canControlMemberAccessible; | |
} | |
private static boolean canControlMemberAccessible() { | |
try { | |
SecurityManager securityManager = System.getSecurityManager(); | |
if (null != securityManager) { | |
securityManager.checkPermission(new ReflectPermission("suppressAccessChecks")); | |
} | |
} catch (SecurityException e) { | |
return false; | |
} | |
return true; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
java -version | |
# compile | |
javac ConcurrentGetValue.java -cp ognl-3.2.10.jar | |
# run rounds | |
for i in {1..10} | |
do | |
java -cp ognl-3.2.10.jar:javassist-3.24.1-GA.jar:. ConcurrentGetValue 50 | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I could reproduce the exception on Java version 1.6.0_65 and 1.7.0_80.
NoSuchPropertyException is thrown once in 10-20 execution on my 3 years old MacBook Pro.
As the underlying JDK bug was fixed in 8u20 and 8u25, the exception won't be thrown in newer versions.