2

I am trying to read classes from java.base as InputStreams. I already have a method to read classfiles given a File object, but I am unable to obtain File objects, since I'm using JDK 11 and there isn't an rt.jar file anymore. After following this answer, I have roughly the following code (I'm using Scala, but this is essentially a question about Java, hence the tags):

val fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap, loader)

Files.list(fs.getPath("/modules")).forEach { mdl =>
  Files.walk(mdl).forEach { (classFile: Path) =>
    val asFile = classFile.toAbsolutePath.toFile //Here's where I get an exception
    //do stuff with that
  }
}

Unfortunately, when I use classFile.toFile or classFile.toAbsolutePath.toFile, I get an UnsupportedOperationException, which I guess is because it's not a physical file. However, I require a File object to turn into an InputStream and read. How can I get File objects for every classfile in a certain module (or every module) that is part of the JDK?

user
  • 6,723
  • 3
  • 9
  • 37
  • 2
    Side note: when you’re reading your own JRE’s module storage, you don’t need to open the filesystem. Further, there’s no need to do a `list` before `walk`. Just `Files.walk(Paths.get(URI.create("jrt:/"))).forEach(…)` is enough to iterate over the entire JRE. – Holger May 25 '21 at 09:10

1 Answers1

6

You don't necessarily need a File to create an InputStream. You can also use a Path together with Files::newInputStream :

Files.list(fs.getPath("/modules")).forEach(mdl -> {
  try(Stream<Path> stream = Files.walk(mdl)) {
    stream.forEach(classFile -> {
      try (InputStream input = Files.newInputStream(classFile)) {
        ...
      } catch(IOException e) {
        ...
      }
    });
  } catch(IOException e) {
    ...
  }
});
Jorn Vernee
  • 26,917
  • 3
  • 67
  • 80