|
4 | 4 | import java.lang.invoke.MethodHandle;
|
5 | 5 | import java.lang.invoke.MethodHandles;
|
6 | 6 | import java.lang.reflect.Constructor;
|
| 7 | +import java.lang.reflect.Executable; |
7 | 8 | import java.lang.reflect.Method;
|
8 | 9 | import java.lang.reflect.Modifier;
|
9 | 10 | import java.lang.reflect.Type;
|
|
12 | 13 | import java.util.function.Consumer;
|
13 | 14 |
|
14 | 15 | import jakarta.enterprise.inject.spi.BeanManager;
|
15 |
| -import jakarta.enterprise.inject.spi.DeploymentException; |
16 | 16 | import jakarta.enterprise.invoke.Invoker;
|
17 | 17 |
|
| 18 | +import org.jboss.weld.exceptions.DeploymentException; |
| 19 | + |
18 | 20 | class MethodHandleUtils {
|
19 | 21 | private MethodHandleUtils() {
|
20 | 22 | }
|
@@ -46,28 +48,36 @@ private MethodHandleUtils() {
|
46 | 48 | }
|
47 | 49 | }
|
48 | 50 |
|
49 |
| - static MethodHandle createMethodHandle(Method method) { |
50 |
| - MethodHandles.Lookup lookup = Modifier.isPublic(method.getModifiers()) |
51 |
| - && Modifier.isPublic(method.getDeclaringClass().getModifiers()) |
52 |
| - ? MethodHandles.publicLookup() |
53 |
| - : MethodHandles.lookup(); |
| 51 | + private static MethodHandles.Lookup lookupFor(Executable method) throws IllegalAccessException { |
| 52 | + if (Modifier.isPublic(method.getModifiers()) && Modifier.isPublic(method.getDeclaringClass().getModifiers())) { |
| 53 | + return MethodHandles.publicLookup(); |
| 54 | + } |
| 55 | + |
| 56 | + // to create a method handle for a `protected`, package-private or `private` method, |
| 57 | + // we need a private lookup in the declaring class |
| 58 | + Module thisModule = MethodHandleUtils.class.getModule(); |
| 59 | + Class<?> targetClass = method.getDeclaringClass(); |
| 60 | + Module targetModule = targetClass.getModule(); |
| 61 | + if (!thisModule.canRead(targetModule)) { |
| 62 | + // we need to read the other module in order to have privateLookup access |
| 63 | + // see javadoc for MethodHandles.privateLookupIn() |
| 64 | + thisModule.addReads(targetModule); |
| 65 | + } |
| 66 | + return MethodHandles.privateLookupIn(targetClass, MethodHandles.lookup()); |
| 67 | + } |
54 | 68 |
|
| 69 | + static MethodHandle createMethodHandle(Method method) { |
55 | 70 | try {
|
56 |
| - return lookup.unreflect(method); |
| 71 | + return lookupFor(method).unreflect(method); |
57 | 72 | } catch (ReflectiveOperationException e) {
|
58 | 73 | // TODO proper exception handling
|
59 | 74 | throw new RuntimeException(e);
|
60 | 75 | }
|
61 | 76 | }
|
62 | 77 |
|
63 | 78 | static MethodHandle createMethodHandle(Constructor<?> constructor) {
|
64 |
| - MethodHandles.Lookup lookup = Modifier.isPublic(constructor.getModifiers()) |
65 |
| - && Modifier.isPublic(constructor.getDeclaringClass().getModifiers()) |
66 |
| - ? MethodHandles.publicLookup() |
67 |
| - : MethodHandles.lookup(); |
68 |
| - |
69 | 79 | try {
|
70 |
| - return lookup.unreflectConstructor(constructor); |
| 80 | + return lookupFor(constructor).unreflectConstructor(constructor); |
71 | 81 | } catch (ReflectiveOperationException e) {
|
72 | 82 | // TODO proper exception handling
|
73 | 83 | throw new RuntimeException(e);
|
|
0 commit comments