ReflectionUtil.performGlobalReflection(reflections -> reflections.getTypesAnnotatedWith(Catalog.class), catalogClass -> { Catalog annotation = catalogClass.getAnnotation(Catalog.class); String registryModuleMethod = annotation.registryModuleMethod(); AdditionalCatalogRegistryModule registryModule; if (!registryModuleMethod.isEmpty()) { registryModule = ReflectionUtil.callMethodChecked(catalogClass, registryModuleMethod, AdditionalCatalogRegistryModule.class, null); } else { registryModule = new DynamicCatalogRegistryModule<>(); } Method registerAdditionalCatalog = ReflectionUtil.getMethod(AdditionalCatalogRegistryModule.class, "registerAdditionalCatalog", catalogClass); for (Field field : ReflectionUtil.getFieldsOfType(catalogClass, catalogClass)) { if (!Modifier.isStatic(field.getModifiers()) || !Modifier.isPublic(field.getModifiers())) continue; if (!Modifier.isFinal(field.getModifiers())) log(catalogClass).warn("The field \"" + field.getName() + "\" is not final"); Object type = ReflectionUtil.fieldValueChecked(field, catalogClass, null); registerAdditionalCatalog.invoke(registryModule, type); } ReflectionUtil.callMethod(GameRegistry.class, "registerModule", Sponge.getRegistry(), catalogClass, registryModule); });