Re[2]: Add posibility to add custom ModuleReaderFactory to ModuleFinder
Alex Sviridov
ooo_saturn7 at mail.ru
Fri Sep 28 12:10:59 UTC 2018
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.Bateman at 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
More information about the jigsaw-dev
mailing list