core/play/src/main/java/play/libs/AnnotationUtils.java
public static <A extends Annotation> List<Annotation> getIndirectlyPresentAnnotations(
      final A maybeContainerAnnotation) {
    try {
      final Method method = maybeContainerAnnotation.annotationType().getMethod("value");
      final Object o = method.invoke(maybeContainerAnnotation);
      if (Annotation[].class.isAssignableFrom(o.getClass())) {
        final Annotation[] indirectAnnotations = (Annotation[]) o;
        if (indirectAnnotations.length > 0
            && indirectAnnotations[0].annotationType().isAnnotationPresent(Repeatable.class)) {
          return Arrays.asList(indirectAnnotations);
        }
      }
    } catch (final NoSuchMethodException e) {
      // That's ok, this just wasn't a container annotation -> continue
    } catch (final SecurityException
        | IllegalAccessException
        | IllegalArgumentException
        | InvocationTargetException e) {
      throw new IllegalStateException(e);
    }
    return Collections.emptyList();
  }
public static <A extends Annotation> List<Annotation> getIndirectlyPresentAnnotations(
      final A maybeContainerAnnotation) {
    try {
      final Method method = maybeContainerAnnotation.annotationType().getMethod("value");
      final Object o = method.invoke(maybeContainerAnnotation);
      if (Annotation[].class.isAssignableFrom(o.getClass())) {
        final Annotation[] indirectAnnotations = (Annotation[]) o;
        if (indirectAnnotations.length > 0
            && indirectAnnotations[0].annotationType().isAnnotationPresent(Repeatable.class)) {
          return Arrays.asList(indirectAnnotations);
        }
      }
    } catch (final NoSuchMethodException e) {
      // That's ok, this just wasn't a container annotation -> continue
    } catch (final SecurityException
        | IllegalAccessException
        | IllegalArgumentException
        | InvocationTargetException e) {
      throw new IllegalStateException(e);
    }
    return Collections.emptyList();
  }
If the return type of an existing {@code value()} method of the passed annotation is an {@code
Annotation[]} array and the annotations inside that {@code Annotation[]} array are annotated
with the {@link Repeatable} annotation the annotations of that array will be returned. If the
passed annotation does not have a {@code value()} method or the above criteria are not met an
empty list will be returned instead.

@param maybeContainerAnnotation The annotation which {@code value()} method will be checked for
other annotations
@return The annotations defined by the {@code value()} method or an empty list.