Skip to content

Instantly share code, notes, and snippets.

@am4dr
Last active May 30, 2018 12:37
Show Gist options
  • Save am4dr/3c2ccdd73a48322a39f054dc08dcfc97 to your computer and use it in GitHub Desktop.
Save am4dr/3c2ccdd73a48322a39f054dc08dcfc97 to your computer and use it in GitHub Desktop.
jimfsとGroovy, Grabのサンプル
/*
ただFileSystemとして使うのは問題ないが、Grabでライブラリをロードするスクリプトの体で
jimfs:なスキームのURIを解決できるようにしたい場合はできなくはなかったが、見つけた方法はいいものではなかった
*/
// versions
// Groovy 2.5.0
// JVM 10
@Grapes([
@GrabConfig(systemClassLoader=true),
@Grab('com.google.jimfs:jimfs:1.1'),
@Grab(group='javax.xml.bind', module='jaxb-api', version='2.3.0'), //for groovy 2.5.0 & jvm 10
])
import com.google.common.jimfs.Configuration
import com.google.common.jimfs.Jimfs
import com.google.common.jimfs.SystemJimfsFileSystemProvider
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.spi.FileSystemProvider
// ServiceLoaderで見つけられる
assert ServiceLoader.load(FileSystemProvider).iterator().any { it instanceof SystemJimfsFileSystemProvider }
println "system ${ClassLoader.systemClassLoader}"
println "grab ${Jimfs.class.classLoader}"
// output例
//system jdk.internal.loader.ClassLoaders$AppClassLoader@7591083d
//grab org.codehaus.groovy.tools.RootLoader@6974a715
// ServiceLoader#loadにsystemClassLoaderを指定すると見つからない。`systemClassLoader=true`とは?
//assert ServiceLoader.load(FileSystemProvider, ClassLoader.systemClassLoader).iterator().any { it instanceof SystemJimfsFileSystemProvider }
def fs = Jimfs.newFileSystem(Configuration.unix())
def hello = fs.getPath('/foo').resolve('hello.txt')
Files.createDirectory(hello.parent)
hello.text = 'hello world'
//Files.write(hello, List.of("hello world"), StandardCharsets.UTF_8) // java ver.
assert hello.text == 'hello world'
// 念のため一度実行してクラスの状態をキャッシュ済みの状態にしておく
FileSystemProvider.installedProviders()
// 内部的にはFileSystemProviderはServiceLoader.load(Class<?>, ClassLoader.systemClassLoader)でロードするが、
// それではGrabで得たクラスをロードできないみたいなので、強引にprivateなキャッシュを差し替える
FileSystemProvider.installedProviders = ServiceLoader.load(FileSystemProvider).collect()
def helloUri = hello.toUri()
assert helloUri.toString().startsWith('jimfs://')
// 強引に差し替えていなければ、次の実行でCaught: java.nio.file.ProviderNotFoundException: Provider "jimfs" not found
def helloPath = Paths.get(helloUri)
assert helloPath.text == 'hello world'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment