RFR: 8331467: FileSystems.getDefault fails with ClassNotFoundException if custom default provider is in run-time image [v7]
Alan Bateman
alanb at openjdk.org
Thu Dec 19 08:15:37 UTC 2024
On Wed, 18 Dec 2024 08:27:09 GMT, liyazzi <duke at openjdk.org> wrote:
>> The test change means this test ends up with two copies of the test provider. I'll create an issue in JBS to refactor this test to allow it be used for all cases (class path, module path, linked into run-time image). That would make this much simpler.
>>
>> The bigger question is whether specification of FileSystems.getDefault should be revised to specify how it should work when the default file system provider is deployed as a module (which would cover the case where there the provider has been linked into the a run-time image). The reasons the tests work is because the provider module exports the package with the provider class but it should be possible to fully encapsulate it. I'll try to do some think on what the right thing to do there is.
>
>> The bigger question is whether specification of FileSystems.getDefault should be revised to specify how it should work when the default file system provider is deployed as a module (which would cover the case where there the provider has been linked into the a run-time image). The reasons the tests work is because the provider module exports the package with the provider class but it should be possible to fully encapsulate it. I'll try to do some think on what the right thing to do there is.
>
> For the specification of FileSystems.getDefault,In my opinion, I think there would be 2 things need to be added.
>
> **A**: add instructions for paying attention to circular dependencies when loading the default file system provider. The changes implemented by this PR to ImageFactory have solved the circular dependency problem in the case where the default file system provider is deployed as a module.
>
> **B**: specify what we should do to keep full encapsulation when loading the default file system provider(maybe not one,but a list).The current performance of FileSystems.getDefault is that:
>
> 1. If the default file system provider is on classpath,then it will be in the Unnamed-Module which exports the package that contains the default file system provider.And it is okay.
> 2. If it is on module path,which means the default file system provider is in a Named-Module(this includes the case of linked into run-time image),unless we export the package with the provider class,it would throw IllegalAccessException: java.base -> customfs module.
>
> Because in current specification of FileSystems.getDefault it is going this:
>
>> Each class is loaded, **using the system class loader**, and instantiated by invoking a one argument constructor whose formal parameter type is FileSystemProvider.
>
> It simply uses the `ClassLoader.getSystemClassLoader()` then leading to the performance mentioned above.
>
> For the **B** point, my opinion is that: not just using the system class loader,but we could load provider class like java SPI loads the Service-Provider.Specifically, the code is as follows(change the FileSystems$DefaultFileSystemHolder.getDefaultProvider):
>
>
> // returns default provider
> private static FileSystemProvider getDefaultProvider() {
> // start with the platform's default file system provider
> FileSystemProvider provider = DefaultFileSystemProvider.instance();
>
> // if the property java.nio.file.spi.DefaultFileSystemProvider is
> ...
@liyazzi JDK-8346463 has been integrated so I think we have a better base to add more tests. It includes a `@Disabled` test that run jlink to create a run-time image that includes the custom default provider. You should be able to remove `@Disabled` to test the changes in this PR.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/22628#issuecomment-2553031244
More information about the core-libs-dev
mailing list