Upplication / Amazon-S3-FileSystem-NIO2

An S3 File System Provider for Java 7
MIT License
122 stars 67 forks source link

S3 FileSystemProvider Not added to Installed Providers after FileSystems.newFileSystem( called) #64

Closed ulmermark closed 7 years ago

ulmermark commented 8 years ago

I have 2 classes that attempt to use the S3 FileSystem provided by this library.

I am loading the S3 FileSYstem from a JAR so I have not added anything to the CLASSPATH or in the extension directory.

Both classes on startup of the application call ( where scheme is S3)

        this.fs = FileSystems.getFileSystem(new URI(scheme+":///"));            

Both throw FileSystemNotFoundException which in turn calls:

this.fs = FileSystems.newFileSystem(new URI(scheme+":///"), new HashMap<String,Object>(), Thread.currentThread().getContextClassLoader());

The 1st class instantiated, all works fine...the S3 File System is created and I have a handle to the FileSystem implementation.

The 2nd class instantiated calls:

this.fs = FileSystems.getFileSystem(new URI(scheme+":///"));

and FileSystemNotFoundException is thrown again, which causes a call to

this.fs = FileSystems.newFileSystem(new URI(scheme+":///"), new HashMap<String,Object>(), Thread.currentThread().getContextClassLoader());

which NOW throws FileSystemAlreadyExistsException ( from the S3FileSystemProvider.newFileSystem(...)

I believe it to be a flaw in the java.nio.file package as a newly created FileSystem is not added to the list of installedProviders.

So the sequence of getFileSystem(s3) newFileSystem(s3) getFileSYstem(S3)

will continue to throw FileSYstemNotFoundException.

Any work arounds besides some how making the S3FileSystem implementation a Singleton and referencing it from both classes??

jarnaiz commented 7 years ago

Hello ulmermark,

Im not sure if Im understanding well your issue... a test case is always the better documentation. I wrote this test trying to reproduce your scenario and its working:

     @Test
    public void test() throws URISyntaxException, IOException {
        // 1º  class works file
        FileSystem fs = null;
        try {
            fs = FileSystems.getFileSystem(new URI("s3:///"));
            fail("must throw exception");
        }catch (FileSystemNotFoundException e) {
            fs = FileSystems.newFileSystem(new URI("s3:///"), new HashMap<>(), Thread.currentThread().getContextClassLoader());
            assertTrue(fs instanceof  S3FileSystem);
        }

        // 2º class invocation

        FileSystem fs1 = FileSystems.getFileSystem(new URI("s3:///"));
        assertTrue(fs1 instanceof  S3FileSystem);
        assertSame(fs1, fs);
    }

Can you try this test in your project?

Cheers!

jarnaiz commented 7 years ago

Try to review if you have the amazon.properties added in some cases and not in others

jarnaiz commented 7 years ago

im going to close this issue. If you have any new information, please open a new issue and refer this one.

szkxv6 commented 6 years ago

Hi, I know this is old, but I didn't want to open an issue if I'm just being stupid. However, I'm getting what appears to be the same issue as the original post here. I'm using version 2.2.2 through Maven. I can run the above test perfectly fine, but when it comes to using the exact same code in that project, I'm seeing the issue.

I'm doing something like this...

System.out.println("####### " + Arrays.toString(FileSystemProvider.installedProviders().toArray()));
try
{
    fs = FileSystems.newFileSystem(URI.create("s3:///"), new HashMap<>(), Thread.currentThread().getContextClassLoader());
}
catch (Exception e)
{
    e.printStackTrace();
}

System.out.println("####### Scheme: " + fs.provider().getScheme());
System.out.println("####### " + Arrays.toString(FileSystemProvider.installedProviders().toArray()));

My output is:

####### [sun.nio.fs.WindowsFileSystemProvider@3cce9f30, com.sun.nio.zipfs.ZipFileSystemProvider@308afd7f]
####### Scheme: s3
####### [sun.nio.fs.WindowsFileSystemProvider@3cce9f30, com.sun.nio.zipfs.ZipFileSystemProvider@308afd7f]

So this says to me the filesystem is loading fine, but not being added to the installed list... or am I mistaking something? So when it comes to finding it, I get errors like the original poster, and if I load it again, it says it already exists. Is there something obvious I should be doing to load - as in not doing it in a particular place or circumstance?

My knowledge, especially in this area isn't that great, so I could be missing something obvious. But presumably I have the prerequisites right, otherwise it surely couldn't have loaded the libraries/filesystem to start with!?

For some context, I'm attempting to use this in Apache Mina SSHD, and I really don't know the best place to try setting it up - as in an ideally place to load the filesystem. It is also running as a listener under Tomcat if that helps and potentially affects it.

Any ideas would be welcome as this is the closest post I have seen to what I am experiencing. Again, apologies if I have done something silly.

Regards.