DiscoverableSubtypeResolver(String rootClassName) { final ImmutableList.Builder<Class<?>> subtypes = ImmutableList.builder(); for (Class<?> klass : discoverServices(rootClassName)) { for (Class<?> subtype : discoverServices(klass.getName())) { subtypes.add(subtype); registerSubtypes(subtype); } } this.discoveredSubtypes = subtypes.build(); }
private List<Class<?>> discoverServices(String className) { final List<Class<?>> serviceClasses = new ArrayList<>(); try { // use classloader that loaded this class to find the service descriptors on the classpath // better than ClassLoader.getSystemResources() which may not be the same classloader if ths app // is running in a container (e.g. via maven exec:java) final Enumeration<URL> resources = getClassLoader().getResources("META-INF/services/" + className); while (resources.hasMoreElements()) { final URL url = resources.nextElement(); try (InputStream input = url.openStream(); InputStreamReader streamReader = new InputStreamReader(input, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(streamReader)) { String line; while ((line = reader.readLine()) != null) { try { serviceClasses.add(getClassLoader().loadClass(line.trim())); } catch (ClassNotFoundException e) { LOGGER.info("Unable to load {}", line); } } } } } catch (IOException e) { LOGGER.warn("Unable to load META-INF/services/{}", className, e); } return serviceClasses; } }
@Test public void testDiscoverKvsConfigSubtypes() { DiscoverableSubtypeResolver subtypeResolver = new DiscoverableSubtypeResolver( AtlasDbConfigs.DISCOVERED_SUBTYPE_MARKER); assertThat(subtypeResolver.getDiscoveredSubtypes()).contains(InMemoryAtlasDbConfig.class); List<Class<?>> allDiscoveredSubtypes = subtypeResolver.getDiscoveredSubtypes(); Set<Class<?>> discoveredKvsConfigs = allDiscoveredSubtypes.stream() .filter(KeyValueServiceConfig.class::isAssignableFrom) .collect(Collectors.toSet()); assertThat(discoveredKvsConfigs).containsExactlyInAnyOrder(InMemoryAtlasDbConfig.class, InMemoryAsyncAtlasDbConfig.class); } }
DiscoverableSubtypeResolver(String rootClassName) { final ImmutableList.Builder<Class<?>> subtypes = ImmutableList.builder(); for (Class<?> klass : discoverServices(rootClassName)) { for (Class<?> subtype : discoverServices(klass.getName())) { subtypes.add(subtype); registerSubtypes(subtype); } } this.discoveredSubtypes = subtypes.build(); }
private List<Class<?>> discoverServices(String className) { final List<Class<?>> serviceClasses = new ArrayList<>(); try { // use classloader that loaded this class to find the service descriptors on the classpath // better than ClassLoader.getSystemResources() which may not be the same classloader if ths app // is running in a container (e.g. via maven exec:java) final Enumeration<URL> resources = getClassLoader().getResources("META-INF/services/" + className); while (resources.hasMoreElements()) { final URL url = resources.nextElement(); try (InputStream input = url.openStream(); InputStreamReader streamReader = new InputStreamReader(input, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(streamReader)) { String line; while ((line = reader.readLine()) != null) { try { serviceClasses.add(getClassLoader().loadClass(line.trim())); } catch (ClassNotFoundException e) { LOGGER.info("Unable to load {}", line); } } } } } catch (IOException e) { LOGGER.warn("Unable to load META-INF/services/{}", className, e); } return serviceClasses; } }