Javaアプリケーションは、ネットワーク共有上で利用可能ないくつかのリソースに依存しています。このネットワーク共有はクラスパス上にあり、リソースは実行時にMyClass.class.getResourceAsStream("/myfile.jpg")
を使用して読み取られます。Javaクラスパスのネットワークディレクトリからリソースを正しく読み込むにはどうすればよいですか?
java -Djava.class.path=\\myserver\myshare:C:\myjar.jar MainClass
起動時に共有が利用可能になると、すべてがスムーズに実行されます。共有にある画像ファイルとプロパティファイルは、getResourceAsStream()
を使用して読み取ることができます。ただし、アプリケーションの起動時に共有がオンラインでない場合、のリソースが読み取られる前に共有がオンラインになっても、getResourceAsStream()
を使用して読み取ることはできません。
eclispse + decompilerを使用していくつかの掘り出しを行うと、1つの違いに気付きました。デフォルトのクラスローダーはURLClassLoaderを継承し、そのucp
メンバー(URLClassPath
)にはURLClassPath.Loader
インスタンスのリストが含まれています。最初のシナリオでは、URLClassPath.FileLoader
とURLClassPath.JarLoader
が含まれています。 2番目のシナリオでは、jarローダーのみが含まれています。
javaのように、クラスパスエントリが無効であると判断し、完全に破棄します。
これはなぜですか?どうすればそれを避けることができますか?
- 私はで変更のために、現在のファイルをこのようにロードあまりにも多くの分野があります。
更新 私たちはので、いくつかの理由のリソースをロードされる機構を変更することができません瞬間
- リソースによって、実際に私は何の問題カスタムクラスローダを作成していないサードパーティのコンポーネント
によってロードされている状況がありますが、Iどのようにそれを行うにはいくつかのガイダンスが必要です。
私はこれを試みたが、期待される結果を取得することができませんでした:、
MyUrlClassLoader ctor
url load class java.lang.System
url load class java.nio.charset.Charset
url load class java.lang.String
url load class ClassLoaderMain
Loaded? true
[email protected]
[email protected]
[email protected]
だから私のクラスローダが作成されている:私はjava -cp . -Djava.system.class.loader=MyUrlClassLoader ClassLoaderMain
この出力を実行すると
import java.net.URL;
import java.net.URLClassLoader;
public class MyUrlClassLoader extends URLClassLoader {
public MyUrlClassLoader(ClassLoader parent) {
super(new URL[0], parent);
System.out.println("MyUrlClassLoader ctor");
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
System.out.println("url find class " + name);
return super.findClass(name);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
System.out.println("url load class " + name);
return super.loadClass(name);
}
@Override
public URL getResource(String name) {
System.out.println("url get resource " + name);
return super.getResource(name);
}
}
import java.net.URL;
public class ClassLoaderMain {
public static void main(String[] args) throws ClassNotFoundException {
URL url = ClassLoaderMain.class.getResource("/myfile.txt");
System.out.print("Loaded? ");
System.out.println(url != null);
System.out.println(ClassLoaderMain.class.getClassLoader().toString());
System.out.println(MyUrlClassLoader.class.getClassLoader().toString());
System.out.println(FakeClass.class.getClassLoader().toString());
}
}
をロードクラスが呼び出されていますが、ロードしているクラスのクラスローダーではないようですか?
おそらく最も安全な方法は、独自のクラスローダーを作成することです。あなたが完全にコントロールしていることを意味します。 – biziclop
シンプルなケースでこれをどうやってやるのですか?私が今までに見たリソースはすべて、実行時にクラスを名前(Class.forName( "string")など)でロードするために使用されているようです。新しいクラスローダーを手動で作成して呼び出すために、 'getResourceAsStream()'へのすべての呼び出しを変更する必要はありません。 – Travis
FileとFileInputStreamを使用してファイルにアクセスできないのはなぜですか? – pauli