Hi Alan Thank you for your answer. But my main problem is not jars inside .war - this is a so far from my current problem. Now I need to 1) add .war file to layer 2). to map file location, for example instead of "module-info.java" I must find "WEB-INF/classes/module-info.java" etc. That is all I need. How can I do it without implementing ModuleFinder?
Best regards, Pavel >Пятница, 28 сентября 2018, 15:03 +03:00 от Alan Bateman ><alan.bate...@oracle.com>: > >On 28/09/2018 10:01, Alex Sviridov wrote: >> From java 9 we can create JPMS layers and dynamically add modules to it. At >> the same time different types of java archives can be JPMS modules - .jar, >> .war, .ear. However, the problem is that it is possible to add only .jar >> archives by default. I opened an issue here >> https://bugs.openjdk.java.net/browse/JDK-8203330 and as it was found out it >> is necessary to implement custom ModuleFinder. >> >> Trying to implement ModuleFinder I understood that it is necessary to >> rewrite (or take from) the "half" of jdk.intenal what is a very bad way. >> >> Lets' consider what I need to add .war arhives to JPMS layer. I need: 1) to >> understand if I can work with this type of archive or I can not (if .war is >> supported) 2). to map file location, for example instead of >> "module-info.java" I must find "WEB-INF/classes/module-info.java" etc. For >> that I don't need to create ModuleDescriptor, ModuleReference, ModuleFinder. >> >> So I suggest to overload ModuleFinder.of() method adding as a parameter >> custom ModuleReaderFactory. For example to add >> ModuleFinder#of(ModuleReaderFactory factory, Path... entries). >> ModuleReaderFactory must have such method - createModuleReader(Path path). >> Such solution will also help Jakarta EE developers a lot of. >> >Creating a ModuleFinder that can find modules in WAR files shouldn't >need any API additions or copying of code from the JDK. Where are the >pain points that you are running into? Is it because a WAR files is >single artifact that may contain several modules (the application module >under WEB-INF/classes and dependences are packaged as JAR files under >WEB-INF/lib). One thing to be aware of is that the zip file system >provider was updated recently to improve its support for opening JAR >files in custom file systems, this means you can do things like this: > > ClassLoader scl = ClassLoader.getSystemClassLoader(); > try (FileSystem warfs = FileSystems.newFileSystem(war, scl)) { > Path classes = warfs.getPath("/WEB-INF/classes"); > Files.walk(classes) > .map(p -> classes.relativize(p)) > .forEach(System.out::println); > > Path lib = warfs.getPath("WEB-INF/lib"); > Files.find(lib, 1, (path, attrs) -> >path.toString().endsWith("jar")) > .forEach(jar -> { > try (FileSystem jarfs = >FileSystems.newFileSystem(jar, scl)) { > Path top = jarfs.getPath("/"); > Files.walk(top) > .map(p -> top.relativize(p)) > .forEach(System.out::println); > } catch (IOException ioe) { > throw new UncheckedIOException(ioe); > } > }); > } > >Another thing to be aware of is that the ModuleFinder.of(Path[]) can >also deal with JAR files that are packaged inside other JAR files. It >does have to extract them to a temporary location on the file system and >there may several potential improvements that could be just, just hasn't >been an area to spend time on. > >-Alan. > > > -- Alex Sviridov