Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8322419

ModulePath.findAll does not handle exploded archive the same as jar file

    XMLWordPrintable

Details

    Description

      A DESCRIPTION OF THE PROBLEM :
      When you want to find modules using ModuleFinder.of(Path... entries).findAll() the entries parameter contains Path objects leading to a file or a folder.

      When the Path object lead to a jar everything works fine and module, automatic module and classpath module are successfully resolved.

      When the Path object lead to a directory, first the code checks for module-info.class (@See ModulePath.scan(Path entry) and if the file exists then the module is loaded.

      But if it does not exists then no check for automatic-module (META-INF/MANIFEST.MF) or a standard library.
      In this case the code expects a list of folder containing modules and will handle each sub entry using ModulePath.readModule(Path entry, BasicFileAttributes attrs)

      Again, if the sub entry is a jar or jmod everything is handled successfully but if it is a folder then the function ModulePath.readExplodedModule(Path dir) will handle the case and if the folder does not contains a file module-info.class then again no check is done for automatic-module (META-INF/MANIFEST.MF) or a standard library only a comment "// for now" that let me think the cases were expected but not handled.

      From my understanding, at this step, directory have to be handled the same than jar file in ModulePath.deriveModuleDescriptor(JarFile jf)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      ModuleFinder.of(jarFile).findAll()
      ModuleFinder.of(extractedJarFile).findAll()

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      both commands must return the same result
      ACTUAL -
      Automatic-Module and standard library aren't returned

      ---------- BEGIN SOURCE ----------
      import java.io.File;
      import java.io.FileOutputStream;
      import java.lang.module.ModuleFinder;
      import java.nio.file.Files;
      import java.util.zip.ZipEntry;
      import java.util.zip.ZipOutputStream;

      public class Proof {

          private static final String ROOT_FOLDER = ".";
          private static final String TEST_FOLDER = "test";
          private static final String MODULE_FOLDER = "modul";
          private static final String PACKAGE_NAME = "somepackage";
          private static final String META_INF = "META-INF";
          private static final String MANIFEST = """
                  Manifest-Version: 1.0
                  Automatic-Module-Name: automatic.modul
                  """;
          private static final String RESOURCE_NAME = "res.txt";
          private static final String RESOURCE_CONTENT = "somecontent";

          private static final String JAR_NAME = "auto-1.0.0.jar";

          public static void main(String[] args) throws Exception {

              File root = new File(ROOT_FOLDER);

              File testFolder = new File(root, TEST_FOLDER);
              testFolder.mkdirs();

              File parentFolder = new File(testFolder, "parent");
              parentFolder.mkdirs();

              File moduleFolder = new File(parentFolder, MODULE_FOLDER);
              moduleFolder.mkdirs();

              File packageFolder = new File(moduleFolder, PACKAGE_NAME);
              packageFolder.mkdirs();

              File metaFolder = new File(moduleFolder, META_INF);
              metaFolder.mkdirs();

              File manifestFile = new File(metaFolder, "MANIFEST.MF");

              File resourceFile = new File(packageFolder, RESOURCE_NAME);

              //create the MANIFEST.MF
              Files.write(manifestFile.toPath(), MANIFEST.getBytes());

              //add resource in package
              Files.write(resourceFile.toPath(), RESOURCE_CONTENT.getBytes());

              //create the jar file
              File jarFile = new File(testFolder, JAR_NAME);
              try (FileOutputStream fos = new FileOutputStream(jarFile);
                      ZipOutputStream zos = new ZipOutputStream(fos)) {

                  // add manifest
                  ZipEntry ze = new ZipEntry(META_INF + "/" + manifestFile.getName());
                  zos.putNextEntry(ze);
                  zos.write(Files.readAllBytes(manifestFile.toPath()));
                  zos.closeEntry();

                  // add simple resource
                  ze = new ZipEntry(PACKAGE_NAME + "/" + resourceFile.getName());
                  zos.putNextEntry(ze);
                  zos.write(Files.readAllBytes(resourceFile.toPath()));
                  zos.closeEntry();
              }

              System.out.println("\n\nFind the automatic module from the jar\n");
              var setOfFoundModule = ModuleFinder.of(jarFile.toPath()).findAll();
              if (setOfFoundModule.isEmpty()) {
                  System.out.println("I found nothing when a jar file is provided");
              } else {
                  System.out.println("I found something when a jar file is provided");
                  setOfFoundModule.forEach(m -> System.out.println("I found:" + m.descriptor().name()));
              }

              System.out.println("\n\nFind the automatic module from module folder\n");
              setOfFoundModule = ModuleFinder.of(moduleFolder.toPath()).findAll();
              if (setOfFoundModule.isEmpty()) {
                  System.out.println("I found nothing when an exploded module is provided");
              } else {
                  System.out.println("I found something when an exploded module is provided");
                  setOfFoundModule.forEach(m -> System.out.println("I found:" + m.descriptor().name()));
              }

              System.out.println("\n\nFind the automatic module from the parent of the module folder\n");
              setOfFoundModule = ModuleFinder.of(parentFolder.toPath()).findAll();
              if (setOfFoundModule.isEmpty()) {
                  System.out.println("I found nothing when the parent folder of an exploded module is provided");
              } else {
                  System.out.println("I found something when the parent folder of an exploded module is provided");
                  setOfFoundModule.forEach(m -> System.out.println("I found:" + m.descriptor().name()));
              }
          }

      }

      ---------- END SOURCE ----------

      FREQUENCY : always


      Attachments

        Activity

          People

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: