Search code examples
javamodulezipzipinputstream

Is there a way to read programmatically a .jmod file in Java?


I opened a .jmod file with 7-zip and I can see the contents. I tried to read it with ZipInputStream programmatically but it doesn't work: does someone know how to do it?


Solution

  • There is no documentation in JEP 261: Module System regarding the format used by JMOD files. That's not an oversight, as far as I can tell, because leaving the format as an implementation detail means they can change the format, without notice, whenever they want. That being said, currently JMOD files appear to be packaged in the ZIP format; this other answer quotes the following from JEP 261:

    The final format of JMOD files is an open issue, but for now it is based on ZIP files.

    However, I can't find that quote anywhere in JEP 261. It looks to be from an older version of the specification—at least, I found similar wording in the history of JDK-8061972 (the issue associated with the JEP).

    What this means is you should—for the time being—be able to read a JMOD file by using any of the APIs which allow reading ZIP files. For instance, you could use one of the following:

    1. The java.util.zip API:

      import java.io.File;
      import java.io.IOException;
      import java.util.zip.ZipFile;
      
      public class Main {
      
        public static void main(String[] args) throws IOException {
          var jmodFile = new File(args[0]).getAbsoluteFile();
          System.out.println("Listing entries in JMOD file: " + jmodFile);
      
          try (var zipFile = new ZipFile(jmodFile)) {
            for (var entries = zipFile.entries(); entries.hasMoreElements(); ) {
              System.out.println(entries.nextElement());
            }
          }
        }
      }
      

      Note: To read the contents of an entry, see ZipFile#getInputStream(ZipEntry).

    2. The ZIP FileSystemProvider API:

      import java.io.IOException;
      import java.nio.file.FileSystems;
      import java.nio.file.Files;
      import java.nio.file.Path;
      
      public class Main {
      
        public static void main(String[] args) throws IOException {
          var jmodFile = Path.of(args[0]).toAbsolutePath().normalize();
          System.out.println("Listing entries in JMOD file: " + jmodFile);
      
          try (var fileSystem = FileSystems.newFileSystem(jmodFile)) {
            Files.walk(fileSystem.getRootDirectories().iterator().next())
                .forEachOrdered(System.out::println);
          }
        }
      }
      

      Note: To read the contents of an entry, use one of the many methods provided by the java.nio.file.Files class.

      Note: The Path#of(String,String...) method was added in Java 11 and the FileSystems#newFileSystem(Path) method was added in Java 13. Replace those method calls if using an older version of Java.


    To reiterate, however: The format used by JMOD files is not documented and may change without notice.