2016-08-21 11 views
1

Gradleを使用するようにJavaプロジェクトを移行しました。これはIntelliJでもコマンドラインを使っても問題ありません。JARからのリソースファイルのリスト

しかし、スタンドアロンのJARにFatJarを使ってパッケージ化すると、プロジェクトのリソースにアクセスする際に問題が発生します。

ここに現在のコードがあります。これは、queriesフォルダから.sqlファイルを再帰的にリストし、各ファイルごとにMapに格納します。

private static void loadQueriesFrom(final String baseDir) throws IOException { 
    final InputStream is = Queries.class.getResourceAsStream(baseDir); 

    if (is == null) 
     return; 

    List<String> queryFiles = IOUtils.readLines(is, Charsets.UTF_8); 

    for (String queryFile: queryFiles) { 
     final int index = queryFile.lastIndexOf(".sql"); 

     if (index == -1) { 
      loadQueriesFrom(baseDir + queryFile + "/"); // directory 
     } 
     else { 
      final String queryName = queryFile.substring(0, index).toLowerCase(); 

      queries.put(baseDir.substring(QUERY_DIRECTORY.length()) + queryName, IOUtils.toString(Queries.class 
        .getResourceAsStream(baseDir + queryFile))); 

     } 
    } 

} 

// First call is 
loadQueriesFrom("/queries"); 

次のように私のディレクトリ構造は次のとおりです。

- src 
    - main 
     - java 
     - resources 
      - queries 
    - test 

コードのこの作品は、それがJARにパッケージされている場合を除き、正常に動作します:この場合には、(ライン1)は常にnullであります。ここに私のfatjar構成です:私はの.jar生成されたファイルを開くと、構造が

- org 
    - mypackage 
     ... 
- queries 

のように見えます

task fatjar(type: Jar) { 
    baseName = project.name 
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    with jar 
    manifest { 
     attributes 'Implementation-Title': 'My project name', 'Implementation-Version': version 
     attributes 'Main-Class': 'org.mypackage.MyMainClass' 
    } 
} 

のでフォルダはJARではなく、いくつかの理由のために含まで問い合わせるgetResourceAsStreamはリストできません。ただし、個々のファイルにアクセスできます。次の行を挿入すると、意図した結果が得られます。

私が試した何
Queries.class.getResourceAsStream("/queries/collaborators/get_collab_list.sql") 

:私が見たgetClassLoader().getResourceAsStream(...)

によって

  • getResourceAsStream(...)を変更queries

  • /queriesを変更

  • 両方

    this answerですが、ちょっと残酷に見えます。

ヘルプありがとうございます。ありがとう!

+0

は、このSOを見てみます答え:[http://stackoverflow.com/questions/5193786/how-to-use-classloader-getresources-correctly/5194049#5194049](http://stackoverflow.com/questions/5193786/how-to-use-クラスローダー - getresources-正しく/ 5194049#5194049)それをファイルに変換する代わりに、URL.openStreamのストリームを使用してコンテンツを読み込むだけです。 – daotan

答えて

2

ディレクトリリソースをファイルに変換します。その最も基本的な形で、例外を無視すると、このようなものになります:あなたはファイルツリー再帰する場合

URL url = Queries.class.getResource("/queries"); 
File dir = new File(url.toURI()); 
for (File file : dir.listFiles()) { 
    // do something with file 
} 

は:

void doSomething(File file) { 
    // do something with file 
} 

void processFile(File file) { 
    if (file.isDirectory()) { 
     for (File sub : file.listFiles()) { 
      processFile(sub); 
     } 
    } else { 
     doSomething(file); 
    } 
} 

を、その後

URL url = Queries.class.getResource("/queries"); 
File dir = new File(url.toURI()); 
processFile(dir); 
+0

あなたの解決策はうまくいかず、FileコンストラクタはURIが無効である(_not hierarchical_)という例外を投げました。クエリをロードする方法を変更しました(すべてのプリロードの代わりに遅延ロード+キャッシュ)。私はあなたの答えをありがとうと、とにかくそれを取り戻すことができないので、あなたに恩恵を与えるでしょう。 :-) – christophetd

+0

(私はまだ恩恵を与えることはできません) – christophetd

関連する問題