Jar に含まれるリソースを検索する
概要
Java のコードから Jar に含まれるリソースファイルを取得する場合は,おそらく最も単純な方法だと ClassLoader#getResource(String)
メソッドなどを使うことになると思います.
ですが,「指定した名前のリソースを取得」するというよりも,「名前が特定のパターンのリソースをすべて取得」したいといった状況もあるのではないでしょうか.
そのようなことはどうすればいいのか調べていたところ
といった解決策を見つけることができました.
Corn CPS
Corn Classpath Scanner (略して CPS) は,その名の通りクラスパスの探索を行うためのライブラリです.
- Web サイト: https://sites.google.com/site/javacornproject/corn-cps
- リポジトリ: https://svn.code.sf.net/p/corn/corn-cps/code/
- クラス: CPScanner
使ってみる
<dependency> <groupId>net.sf.corn</groupId> <artifactId>corn-cps</artifactId> <version>1.1.10</version> </dependency>
例えば "default_*.png" といったパターンの名前を持つリソースを見つけるには,次のようにします.
List<URL> urls = CPScanner.scanResources(new ResourceFilter().resourceName("default_*.png"));
ちなみに,これで返ってくる URL は jar:file:/...
といった値になっています.
こういった URL にアクセスするために,Java には JarURLConnection
というクラスが用意されているということに初めて気がつきました.
(普段 ClassLoader#getResourceAsStream(String)
でストリームを直接取っていた)
PathMatchingResourcePatternResolver
こちらは Spring Framework に含まれているクラスです.
すでに Spring を使っている環境ではこちらの方が導入の手間がなくて済むのかもしれません.
(逆に,リソースの検索のためだけに Spring のライブラリを入れるというのもどうかと思います)
- Web サイト: Spring Framework
- リポジトリ: https://github.com/spring-projects/spring-framework
- クラス: PathMatchingResourcePatternResolver
使ってみる
pom.xml にライブラリを追加します:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.1.4.RELEASE</version> </dependency>
先ほどの例のように "default_*.png" といったパターンの名前を持つリソースを見つけるには,次のようにします.
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("classpath*:/**/default_*.png");
ここで返ってくるのは org.springframework.core.io.Resource 型の値です.
リソースの内容は Resource#getInputStream()
メソッドなどを使えば読み出すことができます.
リソース検索の仕組み
これらのライブラリの中身はどのようなことをしているのだろう?と思って,CPScanner のソースを見てみました. 見てみましたが,僕にはパッと見では何故これで求めているリソースが取得できるのか理解できませんでした……
おわり
Jar の中から特定パターンの名前を持つリソースを検索するライブラリとして Corn CPS と PathMatchingResourcePatternResolver を紹介しました. 便利なライブラリがあったものですが,使うだけでなく余裕があるときに中身も読んで理解していきたいものです.