> > There's no requirements that a module must be stored in a JAR file. In > fact, your program will not work if it was packaged into an image > produced by jlink. That's why we have the ModuleReader::list() API.
I understand this, but it is not uncommon for code that has made such assumptions. Maintaining this assumption can reduce some pain. Take my program as an example. It is a plugin. I hope it can be used in a modular way, but I'm sure no one will use it for jlink in this century. The module API does solve the problem, but I will avoid using it because I am careful to maintain compatibility with Java 8, whether I call these APIs with reflection or multi jar, the build or test process becomes more complex. If the old API still works, I don't want to use the new API. Could you explain what the actual scenario is? Is it for patching the > contents of a module (similar to --patch-module)? Ah, these are some strange use cases. They splice an exe file and a jar file together so that the file can be executed directly and is a jar file. It also needs to find its own location and read the contents of exe from its own head. I think this is a strange and rare use case. I vaguely remember several use cases that assume their own jar state, but I can't recall it for a moment, so I casually use it as an example. Ioi Lam <ioi....@oracle.com> 于2021年10月15日周五 上午12:07写道: > On 10/14/21 8:29 AM, Glavo wrote: > > > > In fact, I don't understand why people started packing JAR files > > inside > > JAR files. Maybe there were some esoteric reasons (related to > > Class-Path: attribute in manifest files???). > > > > > > Sometimes it's necessary to keep jars intact and distribute them as > > they are. In fact, a program I just developed today is not compatible > > with your solution: It uses > > cls.getProtectionDomain().getCodeSource().getLocation() > > find its place, create a zip file system and traverse some of its > folders. > > > > Since we are discussing about a solution for storing modules in a single > file, there's an API to list all the contents of a module -- > java.lang.module.ModuleReader::list(). > > Here's an example: > > import java.lang.module.*; > > public class FindAllInModule { > public static void main(String args[]) throws Exception { > Module module = java.lang.Object.class.getModule(); > ModuleReference mref = module.getLayer().configuration() > .findModule(module.getName()) > .orElseThrow(() -> new RuntimeException()) > .reference(); > try (ModuleReader reader = mref.open()) { > reader.list().forEach(n -> System.out.println(n)); > } > } > } > > > There's no requirements that a module must be stored in a JAR file. In > fact, your program will not work if it was packaged into an image > produced by jlink. That's why we have the ModuleReader::list() API. > > > We also have some strange use cases that require additional data to be > > appended before the jar content. Dismantling the jar will destroy the > > data. > > Could you explain what the actual scenario is? Is it for patching the > contents of a module (similar to --patch-module)? > > > Thanks > - Ioi > > > > > Ioi Lam <ioi....@oracle.com <mailto:ioi....@oracle.com>> > > 于2021年10月14日周四 上午8:57写道: > > > > Hi Glavo, > > > > I have simplified my prototype so now there's no need to implement > > new > > URL handlers. > > > > https://github.com/iklam/tools/tree/main/jigsaw/uberjar > > < > https://urldefense.com/v3/__https://github.com/iklam/tools/tree/main/jigsaw/uberjar__;!!ACWV5N9M2RV99hQ!e5b75N_Cpd4IjSBjjO1rN9cnWFTiv-dPnb8qKrG9xrFoL9LH9NDBuNVoO-O7nQ$ > > > > > > Please see the "Super-JAR Demo" section. > > > > The new demo uses standard features supported by the JDK's built-in > > "jar:" URL handler. The only difference with my previous demo is > > that we > > store the "exploded" version of the modules. I.e., the JAR file looks > > like this: > > > > modules/com.lib/com/lib/Lib.class > > modules/com.lib/module-info.class > > ... > > modules/com.simple/com/simple/Simple.class > > modules/com.simple/com/simple/Simple$Foo.class > > modules/com.simple/module-info.class > > > > All the modules are loaded from the /modules directories in the > > JAR file. > > > > The URI for a class looks like this: > > > > > jar:file:///tmp/apps/super-launcher.jar!/modules/com.lib/com/lib/Lib.class > > > > For modularized apps, I think this is a much better approach than the > > traditional Uber-JARs that store JAR files inside a JAR file, > > which will > > require more complex decompression. > > > > In fact, I don't understand why people started packing JAR files > > inside > > JAR files. Maybe there were some esoteric reasons (related to > > Class-Path: attribute in manifest files???). > > > > But, whatever reason they had would not apply to a modular > > application, > > where every component is already in a Jigsaw module. Packing the > > exploded image into a JAR file will be good enough. > > > > ********************** > > > > Going forward, I would suggest -- > > > > [1] Frameworks such as SpringBoot can consider the idea in this > > demo for > > a possible solution for packaging modules > > > > [2] For the JDK, we should investigate supporting a single-file > > packaging format for modules. E.g. extend the --module-path > > command-line > > option to support modules that are stored in a single file (either > > a JAR > > file or an image file produced by jlink). > > > > java --module-path=super-jar.jar -m com.simple > > or > > java --module-path=super-jar.jar -m com.simple > > > > Or even this (with appropriate attributes in the JAR manifest): > > > > java -jar super-jar.jar > > > > I believe [2] is doable as the underpinning support is already in the > > JDK. We need to decide what format to support, how to specify the > > location of the modules directory inside a JAR file, etc. > > > > As always, since the Oracle Java team has limited resources, > > participation from the Java community is very much appreciated and > > encouraged :-) > > > > Thanks > > - Ioi > > > > > > > > On 10/11/21 3:48 PM, Glavo wrote: > > > I mistakenly believe that the implementation of the filesystem > > corresponds > > > exactly to the URL. The problem I really want to express is that > JDK > > > does not support URLs of nested jar file systems. It seems that > this > > > problem still exists in JDK 17. To make matters worse, we can > > use toUri() > > > to convert the path of the file in the nested jar into a URI, > > but this > > > URI is neither accepted by Paths.get > > (java.lang.IllegalArgumentException: > > > URI does not contain path info ex. jar:file:/c:/foo.zip!/BAR) nor > > > converted into a URL (java.net > > < > https://urldefense.com/v3/__http://java.net__;!!ACWV5N9M2RV99hQ!e5b75N_Cpd4IjSBjjO1rN9cnWFTiv-dPnb8qKrG9xrFoL9LH9NDBuNXMJHaheg$ > >.MalformedURLException: > > Nested JAR URLs > > > are not supported). Is this a bug or an expected behavior? > > > > > > Alan Bateman <alan.bate...@oracle.com > > <mailto:alan.bate...@oracle.com>> 于2021年10月12日周二 上午2:58写道: > > > > > >> On 11/10/2021 15:09, Glavo wrote: > > >>> I think this is a great prototype. Based on it, I think such > > requirements > > >>> can also be realized by enhancing jar in these aspects: > > >>> > > >>> 1. Nested jar file system (The ujar file system seems > > unnecessary. > > >>> I never understand why jar file systems cannot be nested.) > > >> This was fixed in JDK 12, are you seeing issues with release > recent > > >> releases? If so then would it be possible to submit a bug with > > a test > > >> case or bring the issue to core-libs-dev? > > >> > > >> -Alan > > >> > > > >