ReflectionUtil { public static ChangesRequiringRestart getChangesRequiringRestart(ConfigInstance from, ConfigInstance to) { Class<?> clazz = from.getClass(); if (!clazz.equals(to.getClass())) { throw new IllegalArgumentException(String.format("%s != %s", clazz, to.getClass())); } try { Method m = clazz.getDeclaredMethod("getChangesRequiringRestart", clazz); m.setAccessible(true); return (ChangesRequiringRestart) m.invoke(from, to); } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); } } private  ReflectionUtil(); static Set<ConfigKey<?>> getAllConfigsProduced(Class<? extends ConfigProducer> producerClass, String configId); static boolean hasRestartMethods(Class<? extends ConfigInstance> configClass); static boolean containsFieldsFlaggedWithRestart(Class<? extends ConfigInstance> configClass); static ChangesRequiringRestart getChangesRequiringRestart(ConfigInstance from, ConfigInstance to); static List<Class<?>> getAllSuperclasses(Class<?> cls);  }
@Test(expected = IllegalArgumentException.class) public void requireThatGetChangesRequiringRestartValidatesParameterTypes() { ReflectionUtil.getChangesRequiringRestart(new RestartConfig(), new NonRestartConfig()); }