groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Schalk Cronjé <ysb...@gmail.com>
Subject Re: Java NIO2 and the Groovy ClassLoader conundrum
Date Thu, 31 May 2018 15:35:18 GMT
Actually I found an issue in the example which incorrectly make it point 
to RootLoader. A better example is this

    @Grab('org.ysb33r.nio:nio-gz-provider-commons:0.1')
    @Grab('org.slf4j:slf4j-simple:1.7.5')

    import java.nio.file.*

    URI gzURI = "gz:/path/to/compressed.gz".toURI()

    FileSystem fs

    def cl = this.class.classLoader
    while( fs == null && cl != null ) {
         println "Trying ${cl}"
         try {
             fs = FileSystems.getFileSystem(gzURI)
         } catch(FileSystemNotFoundException) {
             fs = FileSystems.newFileSystem(gzURI,[:],cl)
         }
         cl = cl.parent
    }

    println "Loaded filesystem '${fs}' using ${cl}"
    Path gzPath = fs.provider().getPath(gzURI)

This produces the following output

    Trying groovy.lang.GroovyClassLoader$InnerLoader@38831718
    Loaded filesystem 'org.ysb33r.nio.provider.gz.GzFileSystem@615091b8'
    using groovy.lang.GroovyClassLoader@481a996b

which shows that GroovyClassLoader can be used to load the 
FileSystemProvider whereas the

On 31/05/2018 08:53, Schalk Cronjé wrote:
>
> HI all,
>
> Java NIO2 providers 
> (https://docs.oracle.com/javase/8/docs/api/java/nio/file/spi/FileSystemProvider.html)

> works by providing filesystems via SPI. Ideally one would just write 
> the appropriate classes and drop them on the classpath . This allows 
> somebody does to write something like:
>
>     Paths.get('gz:/path/to/compressed.gz')
>
> This all works fine when done within a normal application but it fails 
> when used within GroovyConsole or just running a normal Groovy script. 
> ONe would expect the following just to work
>
>     @Grab('org.ysb33r.nio:nio-gz-provider-commons:0.1')
>     @Grab('org.slf4j:slf4j-simple:1.7.5')
>
>     import java.nio.file.*
>
>     Paths.get('gz:/path/to/compressed.gz')
>
> However the following workaround is required
>
>     @Grab('org.ysb33r.nio:nio-gz-provider-commons:0.1')
>     @Grab('org.slf4j:slf4j-simple:1.7.5')
>
>     import java.nio.file.*
>
>     FileSystem fs
>
>     try {
>         fs = FileSystems.getFileSystem(gzURI)
>     } catch(FileSystemNotFoundException) {
>         fs =
>     FileSystems.newFileSystem(gzURI,[:],this.class.classLoader.parent.parent)
>     }
>
>     Path gzPath = fs.provider().getPath(gzURI)
>
> NOTE: Using 
> @GrabConfig(initContextClassLoader=true,systemClassLoader=true) does 
> not solve the problem in this case
>
>
> At Gr8Conf I sat with with Andres, Jochen and Guillaume to work 
> through this. The issue that that providers are loaded via the system 
> class loader, whereas with GroovyConsole and command-line Groovy it 
> will be loaded via an instance of RootLoader. This leads to one having 
> to manually loading the filesystem.
>
> From the point of view of someone using NIO2 providers this is 
> surprising behaviour. One would expect it just to work out of the box 
> (as per the Javadoc for FileSystemProvider).
>
> My question is now. Is there something that can be done to way 
> GroovyConsole and Groovy scripts are started so that the expectd 
> behaviour of NIO2 providers can be obtained? (Maybe adding an 
> additional method to GrabConfig?).
>
> Groovy luck.
>
> -- 
> Schalk W. Cronjé
> Twitter / Ello / Toeter : @ysb33r


-- 
Schalk W. Cronjé
Twitter / Ello / Toeter : @ysb33r


Mime
View raw message