2017-10-05 3 views
1

Javaがクラスローダーの観点からファイルシステムを見ているのは混乱しています。クラスに関連するJavaファイルの場所

私は、EARのAPP-INF/libフォルダにjarファイルがあるとします。このjarファイルには、new File("foo.txt")をインスタンス化するクラスが含まれています。また、foo.txtはjarの横にあるAPP-INF/libフォルダにあります。

次に、このライブラリをWARモジュールで使用しています。さて、コードはまだファイルを見つけますか?それとも、それをEARのルートまたはWARのルートに置かれているのでしょうか?

+1

新しいファイル( "foo.txt")が動作するためには、ファイルは現在の作業ディレクトリに存在する必要があります。クラスパスからデータをロードするには、 'Classloader#getResourceAsInputStream'を使用します。しかし、EAR内でどのように動作するかはわかりません。異なるパーツのクラスパスは分離されていて、互いに直接アクセスすることはできません。 – Thilo

+2

確かに。私が知っているすべてのアプリケーションサーバーでは、単純なファイル操作はクラスローダの動作に依存しません。クラスローダーは単に画像を入力しません。 @Thiloによると、ファイルサーバーの現在の作業ディレクトリに対するファイル名は、それが何であっても解決されます。一部のアプリケーションサーバーは特定のCWSを設定しますが、一部のユーザーは設定しません。このため、実行可能な場合は、ファイルを直接ロードするのではなく、リソースをロードする方が良い場合がよくあります。次に、クラスローダーの振る舞いを考慮する必要があります。さまざまなクラスローダーの見た目に関する規則は、JEE仕様で設定されています。 –

答えて

1

は、私は、ファイルがEARのAPP-INF/libにからあなたのjarファイル内のWARロードは、このように、それはWARのファイルパスに対して検索されますので、WARのルートにあることが必要であることをかなり確信している

これは、それが処理される方法の例でありますクラスパスに

package main; 

import java.io.IOException; 
import java.io.InputStream; 
import java.net.URL; 

public class Test { 

    private Test() { 
     Class<?> c = this.getClass(); 
     ClassLoader cl = c.getClassLoader(); 
     InputStream[] iss = new InputStream[8]; 
     URL[] urls = new URL[8]; 
     iss[0] = c.getResourceAsStream("/resources/txtFile.txt"); 
     iss[1] = c.getResourceAsStream("resources/txtFile.txt"); 
     iss[2] = c.getResourceAsStream("/txtFile.txt"); 
     iss[3] = c.getResourceAsStream("txtFile.txt"); 
     iss[4] = cl.getResourceAsStream("/resources/txtFile.txt"); 
     iss[5] = cl.getResourceAsStream("resources/txtFile.txt"); 
     iss[6] = cl.getResourceAsStream("/txtFile.txt"); 
     iss[7] = cl.getResourceAsStream("txtFile.txt"); 
     urls[0] = c.getResource("/resources/txtFile.txt"); 
     urls[1] = c.getResource("resources/txtFile.txt"); 
     urls[2] = c.getResource("/txtFile.txt"); 
     urls[3] = c.getResource("txtFile.txt"); 
     urls[4] = cl.getResource("/resources/txtFile.txt"); 
     urls[5] = cl.getResource("resources/txtFile.txt"); 
     urls[6] = cl.getResource("/txtFile.txt"); 
     urls[7] = cl.getResource("txtFile.txt"); 
     for (int i = 0; i < 8; i++) 
      System.out.println("iss[" + i + "] is " 
        + String.valueOf(iss[i] == null)); 
     for (int i = 0; i < 8; i++) 
      System.out.println("url[" + i + "] is " 
        + String.valueOf(urls[i] == null)); 

    } 

    public static final void main(String[] args) { 
     new Test(); 
    } 
} 

プリント

iss[0] is false 
iss[1] is true 
iss[2] is true 
iss[3] is true 
iss[4] is true 
iss[5] is false 
iss[6] is true 
iss[7] is true 
url[0] is false 
url[1] is true 
url[2] is true 
url[3] is true 
url[4] is true 
url[5] is false 
url[6] is true 
url[7] is true 
+0

これは_resources_をロードするときに当てはまるかもしれませんが、OPはリソースではなく 'File'オブジェクトについて特別に尋ねます。 –

+0

あなたは私のポストのトップを読んだ?底はほんの少しだった – Dinh

+2

はい、私はそれを読んだ。私はあなたの答えが間違っていると信ずる限り、OPの質問が懸念されている限り。クラスローダの動作は、JEE準拠のアプリケーションサーバの_File_ローディングには影響しません。間違いなくOPは自分のデータファイルを 'File'sではなくリソースとして指定するべきですが、彼はそうではありません。あなたが書いたことを私が誤解した場合、私は謝罪します。 –

1

あなたはjava.io.FileオブジェクトとしてEARファイルの展開には何もアクセスできることに頼ることはできません。

Java EEサーバーは、ファイルシステム内での展開を「爆発的」にする必要はなく、多くはそうしません。一部のベンダーはこれを行うオプションを提供するかもしれませんが、一般的にこの機能に依存することは賢明ではありません。

さらに、EARファイルに組み込まれたプレーンファイルは、クラスローダーを使用して完全にアクセスできなくなります。

EARファイル内でオブジェクトは、EAR/lib jarファイル、EJBモジュール、RARモジュール、またはWEBモジュール(WAR)内にある場合にのみ、クラスローダーからアクセスできます。それでも、他のモジュールで見ることができるモジュールに関する規則は、My ear is not able to find ejb module classesの答えに記載されています。

あなたの質問は非標準のAPP-INF/libディレクトリを参照しています。それが可能なものを発見するためには、ベンダーのドキュメントを参照する必要があります。 WebLogicまたはWebSphereのEAR/libメカニズム(2009年のJava EE 5)の標準化の前兆であることを漠然と思い出しています。

関連する問題