public static List getJava9ModuleArtifacts()

in core/src/main/java/com/spotify/missinglink/Java9ModuleLoader.java [58:115]


  public static List<Artifact> getJava9ModuleArtifacts(BiConsumer<String, Exception> log) {
    List<Artifact> artifacts = new ArrayList<>();
    try {

      final Class moduleFinderClass = Class.forName("java.lang.module.ModuleFinder");
      final Object systemModuleFinder = moduleFinderClass.getMethod("ofSystem").invoke(null);
      final Set moduleReferences =
          (Set) moduleFinderClass.getMethod("findAll").invoke(systemModuleFinder);
      final Class moduleReferenceClass = Class.forName("java.lang.module.ModuleReference");
      final Class moduleReaderClass = Class.forName("java.lang.module.ModuleReader");
      for (final Object moduleReference : moduleReferences) {
        final Object descriptor =
            moduleReferenceClass.getMethod("descriptor").invoke(moduleReference);
        final String moduleName =
            String.valueOf(descriptor.getClass().getMethod("name").invoke(descriptor));
        Object reader = moduleReferenceClass.getMethod("open").invoke(moduleReference);
        try {
          final ArtifactName name = new ArtifactName(moduleName);
          Map<ClassTypeDescriptor, DeclaredClass> classes = new HashMap<>();
          final List<String> readerList =
              ((Stream<String>) moduleReaderClass.getMethod("list").invoke(reader))
                  .filter(className -> className.endsWith(".class"))
                  .collect(Collectors.toList());

          for (String className : readerList) {
            final Optional<InputStream> opened =
                (Optional<InputStream>)
                    moduleReaderClass.getMethod("open", String.class).invoke(reader, className);
            if (!opened.isPresent()) {
              continue;
            }
            try (InputStream inputStream = opened.get()) {
              DeclaredClass declaredClass = ClassLoader.load(inputStream);
              classes.put(TypeDescriptors.fromClassName(className), declaredClass);
            } catch (Exception e) {
              log.accept("Could not read class " + className, e);
            }
          }
          artifacts.add(new ArtifactBuilder().name(name).classes(classes).build());
        } finally {
          try {
            moduleReaderClass.getMethod("close").invoke(reader);
          } catch (InvocationTargetException
              | NoSuchMethodException
              | SecurityException
              | IllegalAccessException e) {
            log.accept("Could not close reader", e);
          }
        }
      }
    } catch (InvocationTargetException
        | NoSuchMethodException
        | IllegalAccessException
        | ClassNotFoundException e) {
      log.accept("Could not read java 9 modules", e);
    }
    return artifacts;
  }