|
14 | 14 | import java.lang.reflect.Parameter;
|
15 | 15 | import java.lang.reflect.Type;
|
16 | 16 | import java.util.ArrayList;
|
| 17 | +import java.util.Arrays; |
17 | 18 | import java.util.Collections;
|
18 | 19 | import java.util.List;
|
19 | 20 |
|
@@ -183,16 +184,70 @@ private static List<JavaBeanParameter> getParameters(Executable executable) {
|
183 | 184 | return Collections.emptyList();
|
184 | 185 | }
|
185 | 186 |
|
186 |
| - List<JavaBeanParameter> parameters = new ArrayList<>( executable.getParameterCount() ); |
| 187 | + int parameterCount = executable.getParameterCount(); |
| 188 | + List<JavaBeanParameter> parameters = new ArrayList<>( parameterCount ); |
187 | 189 |
|
188 | 190 | Parameter[] parameterArray = executable.getParameters();
|
189 | 191 | Class<?>[] parameterTypes = executable.getParameterTypes();
|
190 | 192 | AnnotatedType[] annotatedTypes = executable.getAnnotatedParameterTypes();
|
191 | 193 |
|
| 194 | + Annotation[][] parameterAnnotationsArray = executable.getParameterAnnotations(); |
| 195 | + Annotation[][] annotationsForJDK8303112 = |
| 196 | + recomputeParameterAnnotationsForJDK8303112( parameterArray, parameterAnnotationsArray ); |
| 197 | + |
192 | 198 | for ( int i = 0; i < parameterArray.length; i++ ) {
|
193 |
| - parameters.add( new JavaBeanParameter( i, parameterArray[i], parameterTypes[i], annotatedTypes[i] ) ); |
| 199 | + parameters.add( new JavaBeanParameter( i, parameterArray[i], parameterTypes[i], annotatedTypes[i], |
| 200 | + annotationsForJDK8303112 != null ? annotationsForJDK8303112[i] : null ) ); |
194 | 201 | }
|
195 | 202 |
|
196 | 203 | return CollectionHelper.toImmutableList( parameters );
|
197 | 204 | }
|
| 205 | + |
| 206 | + /** |
| 207 | + * This is a workaround for <a href="https://bugs.openjdk.org/browse/JDK-8303112">JDK-8303112</a>. |
| 208 | + * @param parameters The result of calling {@link Executable#getParameters()} |
| 209 | + * @param parameterAnnotationsArray The result of calling {@link Executable#getParameterAnnotations()} |
| 210 | + * @return A fixed version of {@code parameterAnnotationsArray}, |
| 211 | + * or {@code null} if {@code parameterAnnotationsArray} is fine an unaffected by JDK-8303112. |
| 212 | + */ |
| 213 | + private static Annotation[][] recomputeParameterAnnotationsForJDK8303112(Parameter[] parameters, |
| 214 | + Annotation[][] parameterAnnotationsArray) { |
| 215 | + int parameterCount = parameters.length; |
| 216 | + if ( parameterAnnotationsArray.length == parameterCount ) { |
| 217 | + // Not affected by JDK-8303112 |
| 218 | + return null; |
| 219 | + } |
| 220 | + |
| 221 | + // We're in a situation where parameter.getAnnotation()/parameter.getAnnotations() |
| 222 | + // is buggy when there are implicit/synthetic parameters, |
| 223 | + // because constructor.getParameterAnnotations() (wrongly) ignores implicit/synthetic parameters |
| 224 | + // while parameter.getAnnotations() (rightly) assumes they are present in the array. |
| 225 | + |
| 226 | + Annotation[][] annotationsForJDK8303112; |
| 227 | + annotationsForJDK8303112 = new Annotation[parameterCount][]; |
| 228 | + int nonImplicitNorSyntheticParamIndex = 0; |
| 229 | + for ( int i = 0; i < parameterCount; i++ ) { |
| 230 | + Parameter parameter = parameters[i]; |
| 231 | + if ( parameter.isImplicit() || parameter.isSynthetic() ) { |
| 232 | + annotationsForJDK8303112[i] = new Annotation[0]; |
| 233 | + } |
| 234 | + else if ( nonImplicitNorSyntheticParamIndex < parameterAnnotationsArray.length ) { |
| 235 | + annotationsForJDK8303112[i] = |
| 236 | + parameterAnnotationsArray[nonImplicitNorSyntheticParamIndex]; |
| 237 | + ++nonImplicitNorSyntheticParamIndex; |
| 238 | + } |
| 239 | + else { |
| 240 | + // Something is wrong; most likely the class wasn't compiled with -parameters |
| 241 | + // and so isImplicit/isSynthetic always return false. |
| 242 | + // As a last resort, assume the implicit/synthetic parameters are the first ones. |
| 243 | + nonImplicitNorSyntheticParamIndex = parameterCount - parameterAnnotationsArray.length; |
| 244 | + Arrays.fill( annotationsForJDK8303112, 0, nonImplicitNorSyntheticParamIndex, |
| 245 | + new Annotation[0] ); |
| 246 | + System.arraycopy( parameterAnnotationsArray, 0, annotationsForJDK8303112, |
| 247 | + nonImplicitNorSyntheticParamIndex, parameterAnnotationsArray.length ); |
| 248 | + return annotationsForJDK8303112; |
| 249 | + } |
| 250 | + } |
| 251 | + return annotationsForJDK8303112; |
| 252 | + } |
198 | 253 | }
|
0 commit comments