code: private static List<Class<?>> getAncestorClasses(Object o, Predicate<? super Class<?>> predicate) {
        if (o == null) {
           return Collections.emptyList();
        }
        List<Class<?>> matches = new ArrayList<>();
        Set<Class<?>> seen = new HashSet<>();
        Queue<Class<?>> queue = new LinkedList<>();
        queue.add(o.getClass());
        while (!queue.isEmpty()) {
           Class<?> clazz = queue.remove();
           if (predicate.test(clazz)) {
              matches.add(clazz);
           }
           seen.add(clazz);
           if (clazz.getSuperclass() != null && !seen.contains(clazz.getSuperclass())) {
              queue.add(clazz.getSuperclass());
           }
           for (Class<?> iface : clazz.getInterfaces()) {
              if (!seen.contains(iface)) {
                 queue.add(iface);
              }
           }
        }
        return matches;
     }
docs: Gets all classes associated with (superclasses and interfaces) the given object that pass the given
  predicate.
  
  @param o         The object
  @param predicate The predicate that ancestors must pass.
  @return List of classes including the class of the given object that match the given predicate