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
>>