Circular loading of installed providers detected

Michael Hall mik3hall at gmail.com
Thu Sep 30 09:00:25 UTC 2021



>> 
>> So eliminating the no args is not a fix. Apparently mixing in a JarFSProvider has a conflict?
>> I don’t think my code can handle this itself as it fails with or without the no args.
> I should have been clearer. I meant that if you have a 1-arg constructor then you should be able to remove your code that iterates over the installed provider to find the built-in/default provider.

I do have a 1-arg constructor that gets invoked at application start up and works fine. I had a no args for some reason I don’t remember that would iterate installed providers to find the default ‘file’ provider since thats the only way it could get this information since it is not passed. As far as I can tell now my own code currently never uses this constructor.

However, I wanted to use JShell via api. Apparently in running that wants to make use of a ‘jar’ provider?

at jdk.compiler/com.sun.tools.javac.file.FSInfo.getJarFSProvider(Unknown Source)

In it’s own startup it uses installedProviders()

at java.base/java.nio.file.spi.FileSystemProvider.installedProviders(Unknown Source)

That itself at some point tries to use ServiceLoader to load my provider (again - it was loaded at startup) with a no-arg constructor. From what I sent earlier if I don’t have one you get the following error. If I do have a no-arg to create a functional instance it almost has to use installedProviders() itself to determine the fallback platform provider. Unless I static save the platform provider I get at startup with the 1-arg constructor. Even then if my no-arg constructor does pretty much nothing it still gets errors on every jar file. But no circular error.

Caused by: java.util.ServiceConfigurationError: java.nio.file.spi.FileSystemProvider: us.hall.trz.osx.MacFileSystemProvider Unable to get public no-arg constructor

For some reason, probably because I am currently the default provider it tries to invoke my no-arg constructor. It fails if I don’t have one. It throws the circular error if I have one that also tries to do a installedProviders(). It works but throws errors on every jar file in classpath if I have a no-args that doesn’t do installedProviders()

I can try to recreate this with the jdk test default provider for a bug report but something doesn’t seem to be working right here?

> 
> Also just to say that the spec has always had a warning about recursive initialization:
> 
> "During construction a provider may safely access files associated with the default provider but care needs to be taken to avoid circular loading of other installed providers. If circular loading of installed providers is detected then an unspecified error is thrown."
> 
> -Alan.

I was thinking again for some reason that it wasn’t recursive. It does seem to be. But it is not me that isn’t being careful, jshell apparently uses javac which in turn tries to use a jar provider that attempts to use ServiceLoader to _reload_ my provider. It does this for some reason with a no-arg constructor. 
It isn’t me starting the recursion. 

I don’t know how I can avoid it trying to call me?

Maybe a provider can set something to indicate it has already been loaded and avoid anything trying to reload it again later?

Again, I might be able to recreate this with the jdk test provider if you want?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/nio-dev/attachments/20210930/4f438388/attachment-0001.htm>


More information about the nio-dev mailing list