|
27 | 27 | import java.util.concurrent.CancellationException; |
28 | 28 | import java.util.concurrent.CompletionStage; |
29 | 29 | import java.util.function.Function; |
| 30 | +import java.util.function.Supplier; |
30 | 31 | import java.util.stream.Stream; |
31 | 32 |
|
32 | 33 | public final class CancelMethodsCache { |
@@ -60,58 +61,41 @@ public static Cancellation cancellationOf(Class<?> stageClass) { |
60 | 61 |
|
61 | 62 | private static ExceptionalCancellation cancelInterruptibleMethodOf(Class<?> clazz) { |
62 | 63 | try { |
63 | | - Method m = clazz.getMethod("cancel", boolean.class); |
64 | | - Method mf = firstUnreflectableMethod(m); |
65 | | - if (null != mf) { |
66 | | - try { |
67 | | - MethodHandle mh = MethodHandles.publicLookup() |
68 | | - .unreflect(mf) |
69 | | - .asType(MethodType.methodType(boolean.class, CompletionStage.class, boolean.class)); |
70 | | - return (p, b) -> (boolean)mh.invokeExact(p, b); |
71 | | - } catch (IllegalAccessException ex) { |
72 | | - // will try reflective |
73 | | - } |
| 64 | + Method m = firstUnreflectableMethod( clazz.getMethod("cancel", boolean.class) ); |
| 65 | + if (null == m) { |
| 66 | + return null; |
74 | 67 | } |
75 | | - return (p, b) -> (Boolean)m.invoke(p, b); |
| 68 | + MethodHandle mh = unreflect(m).asType(MethodType.methodType(boolean.class, CompletionStage.class, boolean.class)); |
| 69 | + return (p, b) -> (boolean)mh.invokeExact(p, b); |
| 70 | + //return (p, b) -> (Boolean)m.invoke(p, b); |
76 | 71 | } catch (ReflectiveOperationException | SecurityException ex) { |
77 | 72 | return null; |
78 | 73 | } |
79 | 74 | } |
80 | 75 |
|
81 | 76 | private static ExceptionalCancellation cancelMethodOf(Class<?> clazz) { |
82 | 77 | try { |
83 | | - Method m = clazz.getMethod("cancel"); |
84 | | - Method mf = firstUnreflectableMethod(m); |
85 | | - if (null != mf) { |
86 | | - try { |
87 | | - MethodHandle mh = MethodHandles.publicLookup() |
88 | | - .unreflect(mf) |
89 | | - .asType(MethodType.methodType(boolean.class, CompletionStage.class)); |
90 | | - return (p, b) -> (boolean)mh.invokeExact(p); |
91 | | - } catch (IllegalAccessException ex) { |
92 | | - // will try reflective |
93 | | - } |
| 78 | + Method m = firstUnreflectableMethod( clazz.getMethod("cancel") ); |
| 79 | + if (null == m) { |
| 80 | + return null; |
94 | 81 | } |
95 | | - return (p, b) -> (Boolean)m.invoke(p); |
| 82 | + MethodHandle mh = unreflect(m).asType(MethodType.methodType(boolean.class, CompletionStage.class)); |
| 83 | + return (p, b) -> (boolean)mh.invokeExact(p); |
| 84 | + //return (p, b) -> (Boolean)m.invoke(p); |
96 | 85 | } catch (ReflectiveOperationException | SecurityException ex) { |
97 | 86 | return null; |
98 | 87 | } |
99 | 88 | } |
100 | 89 |
|
101 | 90 | private static ExceptionalCancellation completeExceptionallyMethodOf(Class<?> clazz) { |
102 | 91 | try { |
103 | | - Method m = clazz.getMethod("completeExceptionally", Throwable.class); |
104 | | - Method mf = firstUnreflectableMethod(m); |
105 | | - if (null != mf) { |
106 | | - try { |
107 | | - MethodHandle mh = MethodHandles.publicLookup() |
108 | | - .unreflect(mf) |
109 | | - .asType(MethodType.methodType(boolean.class, CompletionStage.class, CancellationException.class)); |
110 | | - return (p, b) -> (boolean)mh.invokeExact(p, new CancellationException()); |
111 | | - } catch (IllegalAccessException ex) { |
112 | | - } |
| 92 | + Method m = firstUnreflectableMethod( clazz.getMethod("completeExceptionally", Throwable.class) ); |
| 93 | + if (null == m) { |
| 94 | + return null; |
113 | 95 | } |
114 | | - return (p, b) -> (Boolean)m.invoke(p, new CancellationException()); |
| 96 | + MethodHandle mh = unreflect(m).asType(MethodType.methodType(boolean.class, CompletionStage.class, CancellationException.class)); |
| 97 | + return (p, b) -> (boolean)mh.invokeExact(p, new CancellationException()); |
| 98 | + //return (p, b) -> (Boolean)m.invoke(p, new CancellationException()); |
115 | 99 | } catch (ReflectiveOperationException | SecurityException ex) { |
116 | 100 | return null; |
117 | 101 | } |
@@ -139,15 +123,19 @@ private static Method firstUnreflectableMethod(Class<?> clazz, Method m, Set<Cla |
139 | 123 | } |
140 | 124 | } |
141 | 125 | return |
142 | | - Stream.concat(Stream.of(clazz.getSuperclass()), Stream.of(clazz.getInterfaces())) |
143 | | - .filter(Objects::nonNull) |
| 126 | + Stream.concat( Stream.of(clazz.getSuperclass()), Stream.of(clazz.getInterfaces()) ) |
| 127 | + .filter(c -> c != null && !visited.contains(c)) |
144 | 128 | .map(superClazz -> firstUnreflectableMethod(superClazz, m, visited)) |
145 | 129 | .filter(Objects::nonNull) |
146 | 130 | .findFirst() |
147 | 131 | .orElse(null) |
148 | 132 | ; |
149 | 133 | } |
150 | 134 |
|
| 135 | + private static MethodHandle unreflect(Method m) throws IllegalAccessException { |
| 136 | + return MethodHandles.publicLookup().unreflect(m); |
| 137 | + } |
| 138 | + |
151 | 139 | @FunctionalInterface |
152 | 140 | static interface ExceptionalCancellation { |
153 | 141 | boolean apply(CompletionStage<?> p, boolean b) throws Throwable; |
|
0 commit comments