Method (Class<?> aClass) { Method methodWithoutArgsCandidate = null; // static main methods may be only in this class for (Method declaredMethod : aClass.getDeclaredMethods()) { MainMethodStatus status = getMainMethodStatus(declaredMethod, true); if (status == MainMethodStatus.WithArgs) { return declaredMethod; } else if (status == MainMethodStatus.WithoutArgs) { methodWithoutArgsCandidate = declaredMethod; } } if (methodWithoutArgsCandidate != null) { return methodWithoutArgsCandidate; } Deque<Class<?>> classesToVisit = new ArrayDeque<>(); classesToVisit.add(aClass); Set<Class<?>> visited = new HashSet<>(); while (!classesToVisit.isEmpty()) { Class<?> last = classesToVisit.removeLast(); Method[] declaredMethods = last.getDeclaredMethods(); for (Method method : declaredMethods) { MainMethodStatus status = getMainMethodStatus(method, false); if (status == MainMethodStatus.WithArgs) { return method; } else if (status == MainMethodStatus.WithoutArgs) { methodWithoutArgsCandidate = method; } } visited.add(aClass); Class<?> superclass = last.getSuperclass(); if (superclass != null) { classesToVisit.add(superclass); } for (Class<?> anInterface : last.getInterfaces()) { if (!visited.contains(anInterface)) { classesToVisit.add(anInterface); } } } return methodWithoutArgsCandidate; }