Skip to content

Commit fd3b1fa

Browse files
authored
Merge pull request #1321 from harawata/1156-illegal-reflective-access
Avoid unnecessary `setAccessible()` calls.
2 parents b2ad4ee + a9ea248 commit fd3b1fa

File tree

6 files changed

+80
-50
lines changed

6 files changed

+80
-50
lines changed

src/main/java/org/apache/ibatis/reflection/Reflector.java

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,7 @@ private void addDefaultConstructor(Class<?> clazz) {
7777
Constructor<?>[] consts = clazz.getDeclaredConstructors();
7878
for (Constructor<?> constructor : consts) {
7979
if (constructor.getParameterTypes().length == 0) {
80-
if (canControlMemberAccessible()) {
81-
try {
82-
constructor.setAccessible(true);
83-
} catch (Exception e) {
84-
// Ignored. This is only a final precaution, nothing we can do.
85-
}
86-
}
87-
if (constructor.isAccessible()) {
8880
this.defaultConstructor = constructor;
89-
}
9081
}
9182
}
9283
}
@@ -250,26 +241,17 @@ private Class<?> typeToClass(Type src) {
250241
private void addFields(Class<?> clazz) {
251242
Field[] fields = clazz.getDeclaredFields();
252243
for (Field field : fields) {
253-
if (canControlMemberAccessible()) {
254-
try {
255-
field.setAccessible(true);
256-
} catch (Exception e) {
257-
// Ignored. This is only a final precaution, nothing we can do.
244+
if (!setMethods.containsKey(field.getName())) {
245+
// issue #379 - removed the check for final because JDK 1.5 allows
246+
// modification of final fields through reflection (JSR-133). (JGB)
247+
// pr #16 - final static can only be set by the classloader
248+
int modifiers = field.getModifiers();
249+
if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers))) {
250+
addSetField(field);
258251
}
259252
}
260-
if (field.isAccessible()) {
261-
if (!setMethods.containsKey(field.getName())) {
262-
// issue #379 - removed the check for final because JDK 1.5 allows
263-
// modification of final fields through reflection (JSR-133). (JGB)
264-
// pr #16 - final static can only be set by the classloader
265-
int modifiers = field.getModifiers();
266-
if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers))) {
267-
addSetField(field);
268-
}
269-
}
270-
if (!getMethods.containsKey(field.getName())) {
271-
addGetField(field);
272-
}
253+
if (!getMethods.containsKey(field.getName())) {
254+
addGetField(field);
273255
}
274256
}
275257
if (clazz.getSuperclass() != null) {
@@ -335,14 +317,6 @@ private void addUniqueMethods(Map<String, Method> uniqueMethods, Method[] method
335317
// if it is known, then an extended class must have
336318
// overridden a method
337319
if (!uniqueMethods.containsKey(signature)) {
338-
if (canControlMemberAccessible()) {
339-
try {
340-
currentMethod.setAccessible(true);
341-
} catch (Exception e) {
342-
// Ignored. This is only a final precaution, nothing we can do.
343-
}
344-
}
345-
346320
uniqueMethods.put(signature, currentMethod);
347321
}
348322
}

src/main/java/org/apache/ibatis/reflection/factory/DefaultObjectFactory.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.TreeSet;
3030

3131
import org.apache.ibatis.reflection.ReflectionException;
32+
import org.apache.ibatis.reflection.Reflector;
3233

3334
/**
3435
* @author Clinton Begin
@@ -60,16 +61,28 @@ private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgType
6061
Constructor<T> constructor;
6162
if (constructorArgTypes == null || constructorArgs == null) {
6263
constructor = type.getDeclaredConstructor();
63-
if (!constructor.isAccessible()) {
64-
constructor.setAccessible(true);
64+
try {
65+
return constructor.newInstance();
66+
} catch (IllegalAccessException e) {
67+
if (Reflector.canControlMemberAccessible()) {
68+
constructor.setAccessible(true);
69+
return constructor.newInstance();
70+
} else {
71+
throw e;
72+
}
6573
}
66-
return constructor.newInstance();
6774
}
6875
constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
69-
if (!constructor.isAccessible()) {
70-
constructor.setAccessible(true);
76+
try {
77+
return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
78+
} catch (IllegalAccessException e) {
79+
if (Reflector.canControlMemberAccessible()) {
80+
constructor.setAccessible(true);
81+
return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
82+
} else {
83+
throw e;
84+
}
7185
}
72-
return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
7386
} catch (Exception e) {
7487
StringBuilder argTypes = new StringBuilder();
7588
if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) {

src/main/java/org/apache/ibatis/reflection/invoker/GetFieldInvoker.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2017 the original author or authors.
2+
* Copyright 2009-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
1818
import java.lang.reflect.Field;
1919
import java.lang.reflect.InvocationTargetException;
2020

21+
import org.apache.ibatis.reflection.Reflector;
22+
2123
/**
2224
* @author Clinton Begin
2325
*/
@@ -30,7 +32,16 @@ public GetFieldInvoker(Field field) {
3032

3133
@Override
3234
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
33-
return field.get(target);
35+
try {
36+
return field.get(target);
37+
} catch (IllegalAccessException e) {
38+
if (Reflector.canControlMemberAccessible()) {
39+
field.setAccessible(true);
40+
return field.get(target);
41+
} else {
42+
throw e;
43+
}
44+
}
3445
}
3546

3647
@Override

src/main/java/org/apache/ibatis/reflection/invoker/MethodInvoker.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2017 the original author or authors.
2+
* Copyright 2009-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
1818
import java.lang.reflect.InvocationTargetException;
1919
import java.lang.reflect.Method;
2020

21+
import org.apache.ibatis.reflection.Reflector;
22+
2123
/**
2224
* @author Clinton Begin
2325
*/
@@ -38,7 +40,16 @@ public MethodInvoker(Method method) {
3840

3941
@Override
4042
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
41-
return method.invoke(target, args);
43+
try {
44+
return method.invoke(target, args);
45+
} catch (IllegalAccessException e) {
46+
if (Reflector.canControlMemberAccessible()) {
47+
method.setAccessible(true);
48+
return method.invoke(target, args);
49+
} else {
50+
throw e;
51+
}
52+
}
4253
}
4354

4455
@Override

src/main/java/org/apache/ibatis/reflection/invoker/SetFieldInvoker.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2017 the original author or authors.
2+
* Copyright 2009-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
1818
import java.lang.reflect.Field;
1919
import java.lang.reflect.InvocationTargetException;
2020

21+
import org.apache.ibatis.reflection.Reflector;
22+
2123
/**
2224
* @author Clinton Begin
2325
*/
@@ -30,7 +32,16 @@ public SetFieldInvoker(Field field) {
3032

3133
@Override
3234
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
33-
field.set(target, args[0]);
35+
try {
36+
field.set(target, args[0]);
37+
} catch (IllegalAccessException e) {
38+
if (Reflector.canControlMemberAccessible()) {
39+
field.setAccessible(true);
40+
field.set(target, args[0]);
41+
} else {
42+
throw e;
43+
}
44+
}
3445
return null;
3546
}
3647

src/main/java/org/apache/ibatis/reflection/property/PropertyCopier.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2015 the original author or authors.
2+
* Copyright 2009-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
1717

1818
import java.lang.reflect.Field;
1919

20+
import org.apache.ibatis.reflection.Reflector;
21+
2022
/**
2123
* @author Clinton Begin
2224
*/
@@ -32,8 +34,16 @@ public static void copyBeanProperties(Class<?> type, Object sourceBean, Object d
3234
final Field[] fields = parent.getDeclaredFields();
3335
for(Field field : fields) {
3436
try {
35-
field.setAccessible(true);
36-
field.set(destinationBean, field.get(sourceBean));
37+
try {
38+
field.set(destinationBean, field.get(sourceBean));
39+
} catch (IllegalAccessException e) {
40+
if (Reflector.canControlMemberAccessible()) {
41+
field.setAccessible(true);
42+
field.set(destinationBean, field.get(sourceBean));
43+
} else {
44+
throw e;
45+
}
46+
}
3747
} catch (Exception e) {
3848
// Nothing useful to do, will only fail on final fields, which will be ignored.
3949
}

0 commit comments

Comments
 (0)