missing resources when using --patch-module

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

missing resources when using --patch-module

Robert Scholte
This issue was registered as SUREFIRE-1768[1]
It contains a very small Maven project to demonstrate the issue.

That project contains one method executing the following:

Demo.class.getClassLoader().getResources("demo").asIterator().forEachRemaining(url -> {
  System.out.println(url.getFile()); // I'd like to see the target/classes/demo directory here at some point.
});


After executing the test it shows the following result
/E:/test-classpath-demo-master/target/test-classes/demo/
/E:/test-classpath-demo-master/target/test-classes/demo

these are similar, but more worrying: where is 
/E:/test-classpath-demo-master/target/classes/demo

I rewrote it a bit by including a main method  to ensure it is not caused by surefire:
"%JAVA_HOME%"\bin\java --module-path target/classes --patch-module test.classpath.demo=target/test-classes  --module test.classpath.demo/demo.DemoTest


this gave me only one result (where I expected 2):
/E:/test-classpath-demo-master/target/test-classes/demo/


So the question is, where is
/E:/test-classpath-demo-master/target/classes/demo/


thanks,
Robert

[1] https://issues.apache.org/jira/browse/SUREFIRE-1768
Reply | Threaded
Open this post in threaded view
|

Re: missing resources when using --patch-module

Simone Bordet
Hi,

On Fri, Apr 3, 2020 at 11:18 AM Robert Scholte <[hidden email]> wrote:

>
> This issue was registered as SUREFIRE-1768[1]
> It contains a very small Maven project to demonstrate the issue.
>
> That project contains one method executing the following:
>
> Demo.class.getClassLoader().getResources("demo").asIterator().forEachRemaining(url -> {
>   System.out.println(url.getFile()); // I'd like to see the target/classes/demo directory here at some point.
> });
>
>
> After executing the test it shows the following result
> /E:/test-classpath-demo-master/target/test-classes/demo/
> /E:/test-classpath-demo-master/target/test-classes/demo
>
> these are similar, but more worrying: where is
> /E:/test-classpath-demo-master/target/classes/demo
>
> I rewrote it a bit by including a main method  to ensure it is not caused by surefire:
> "%JAVA_HOME%"\bin\java --module-path target/classes --patch-module test.classpath.demo=target/test-classes  --module test.classpath.demo/demo.DemoTest
>
>
> this gave me only one result (where I expected 2):
> /E:/test-classpath-demo-master/target/test-classes/demo/
>
>
> So the question is, where is
> /E:/test-classpath-demo-master/target/classes/demo/

ModulePatcher.PatchedModuleReader.find(String name) does this:

Resource r = findResourceInPatch(name);
if (r != null) {
    URI uri = URI.create(r.getURL().toString());
    return Optional.of(uri);
} else {
    return delegate().find(name);
}

where delegate() returns the non-patched part of the module.

So it either returns one, or the other.

While debugging, I set r=null to see what the delegate would find, and
it does find /E:/test-classpath-demo-master/target/classes/demo/

--
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz
Reply | Threaded
Open this post in threaded view
|

Re: missing resources when using --patch-module

Alan Bateman
In reply to this post by Robert Scholte
On 03/04/2020 10:17, Robert Scholte wrote:

> This issue was registered as SUREFIRE-1768[1]
> It contains a very small Maven project to demonstrate the issue.
>
> That project contains one method executing the following:
>
> Demo.class.getClassLoader().getResources("demo").asIterator().forEachRemaining(url -> {
>    System.out.println(url.getFile()); // I'd like to see the target/classes/demo directory here at some point.
> });
>
>
> After executing the test it shows the following result
> /E:/test-classpath-demo-master/target/test-classes/demo/
> /E:/test-classpath-demo-master/target/test-classes/demo
>
> these are similar, but more worrying: where is
> /E:/test-classpath-demo-master/target/classes/demo
>
> I rewrote it a bit by including a main method  to ensure it is not caused by surefire:
> "%JAVA_HOME%"\bin\java --module-path target/classes --patch-module test.classpath.demo=target/test-classes  --module test.classpath.demo/demo.DemoTest
>
>
> this gave me only one result (where I expected 2):
> /E:/test-classpath-demo-master/target/test-classes/demo/
>
>
> So the question is, where is
> /E:/test-classpath-demo-master/target/classes/demo/
>
Patching is to used to replace specific classes or resources in a module
with alternative versions. It can also be used to augment a module with
new classes or resources. In the reproducer, it looks like module
test.classpath.demo has been patched so that "demo" is found in the
patch rather than the original module. This is correct behavior.

If it helps, this will give a list of the resources in the module so you
can see the effect of the patching:

         String name = this.getClass().getModule().getName();
         ModuleLayer.boot()
                 .configuration()
                 .findModule(name)
                 .orElseThrow()
                 .reference()
                 .open()
                 .list()
                 .forEach(System.out::println)

-Alan
Reply | Threaded
Open this post in threaded view
|

Re: missing resources when using --patch-module

Robert Scholte
Thanks for the explanation, it makes sense:
Patch acts more like an override than an append.

best,
Robert

On 3-4-2020 12:56:10, Alan Bateman <[hidden email]> wrote:
On 03/04/2020 10:17, Robert Scholte wrote:

> This issue was registered as SUREFIRE-1768[1]
> It contains a very small Maven project to demonstrate the issue.
>
> That project contains one method executing the following:
>
> Demo.class.getClassLoader().getResources("demo").asIterator().forEachRemaining(url -> {
>   System.out.println(url.getFile()); // I'd like to see the target/classes/demo directory here at some point.
> });
>
>
> After executing the test it shows the following result
> /E:/test-classpath-demo-master/target/test-classes/demo/
> /E:/test-classpath-demo-master/target/test-classes/demo
>
> these are similar, but more worrying: where is
> /E:/test-classpath-demo-master/target/classes/demo
>
> I rewrote it a bit by including a main method  to ensure it is not caused by surefire:
> "%JAVA_HOME%"\bin\java --module-path target/classes --patch-module test.classpath.demo=target/test-classes  --module test.classpath.demo/demo.DemoTest
>
>
> this gave me only one result (where I expected 2):
> /E:/test-classpath-demo-master/target/test-classes/demo/
>
>
> So the question is, where is
> /E:/test-classpath-demo-master/target/classes/demo/
>
Patching is to used to replace specific classes or resources in a module
with alternative versions. It can also be used to augment a module with
new classes or resources. In the reproducer, it looks like module
test.classpath.demo has been patched so that "demo" is found in the
patch rather than the original module. This is correct behavior.

If it helps, this will give a list of the resources in the module so you
can see the effect of the patching:

        String name = this.getClass().getModule().getName();
        ModuleLayer.boot()
                .configuration()
                .findModule(name)
                .orElseThrow()
                .reference()
                .open()
                .list()
                .forEach(System.out::println)

-Alan
Reply | Threaded
Open this post in threaded view
|

Re: missing resources when using --patch-module

Tom De Wolf
Hi,

I understand that for individual classes and non-java resources a patch
should replace them. However for directories which are actually java
packages this seems to be odd. Does this not make it impossible to add a
new class to an existing package or replace only 1 class in a package but
keep the rest? If only the package found in the patch is returned then only
classes in that patch are found and not the classes in the original package.

Best regards,

Tom- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -



Op vr 3 apr. 2020 om 13:28 schreef Robert Scholte <[hidden email]>:

> Thanks for the explanation, it makes sense:
> Patch acts more like an override than an append.
>
> best,
> Robert
>
> On 3-4-2020 12:56:10, Alan Bateman <[hidden email]> wrote:
> On 03/04/2020 10:17, Robert Scholte wrote:
> > This issue was registered as SUREFIRE-1768[1]
> > It contains a very small Maven project to demonstrate the issue.
> >
> > That project contains one method executing the following:
> >
> >
> Demo.class.getClassLoader().getResources("demo").asIterator().forEachRemaining(url
> -> {
> >   System.out.println(url.getFile()); // I'd like to see the
> target/classes/demo directory here at some point.
> > });
> >
> >
> > After executing the test it shows the following result
> > /E:/test-classpath-demo-master/target/test-classes/demo/
> > /E:/test-classpath-demo-master/target/test-classes/demo
> >
> > these are similar, but more worrying: where is
> > /E:/test-classpath-demo-master/target/classes/demo
> >
> > I rewrote it a bit by including a main method  to ensure it is not
> caused by surefire:
> > "%JAVA_HOME%"\bin\java --module-path target/classes --patch-module
> test.classpath.demo=target/test-classes  --module
> test.classpath.demo/demo.DemoTest
> >
> >
> > this gave me only one result (where I expected 2):
> > /E:/test-classpath-demo-master/target/test-classes/demo/
> >
> >
> > So the question is, where is
> > /E:/test-classpath-demo-master/target/classes/demo/
> >
> Patching is to used to replace specific classes or resources in a module
> with alternative versions. It can also be used to augment a module with
> new classes or resources. In the reproducer, it looks like module
> test.classpath.demo has been patched so that "demo" is found in the
> patch rather than the original module. This is correct behavior.
>
> If it helps, this will give a list of the resources in the module so you
> can see the effect of the patching:
>
>         String name = this.getClass().getModule().getName();
>         ModuleLayer.boot()
>                 .configuration()
>                 .findModule(name)
>                 .orElseThrow()
>                 .reference()
>                 .open()
>                 .list()
>                 .forEach(System.out::println)
>
> -Alan
>
Reply | Threaded
Open this post in threaded view
|

Re: missing resources when using --patch-module

Alan Bateman
On 03/04/2020 12:46, Tom De Wolf wrote:
> Hi,
>
> I understand that for individual classes and non-java resources a
> patch should replace them. However for directories which are actually
> java packages this seems to be odd. Does this not make it impossible
> to add a new class to an existing package or replace only 1 class in a
> package but keep the rest? If only the package found in the patch is
> returned then only classes in that patch are found and not the classes
> in the original package.
Best to read the "Patching module content" section of JEP 261 [1] as it
has the details. Hopefully it will be clear that you are add classes or
resources to an existing package (the classes loaded from that location
will be in the same run-time package as those located from the
equivalent location in the original module).

Just on directories as resources. This is a very under-specific area and
has always been implementation specific as to whether directories are
located as resources, also whether they are synthesized when they don't
exist (e.g. a JAR file might have directory entries stripped, zip -D,
etc). Short comings in the specification of resources pre-date modules.

-Alan

[1] https://openjdk.java.net/jeps/261#Patching-module-content