2012-03-21 13 views
2

私はClassLoaderを持っています。これは、ソースファイルからJavaCompilerでコンパイルされたクラスをロードします。 しかし、ソースファイルを変更して保存して再コンパイルすると、ClassLoaderはまだクラスの最初のバージョンを読み込みます。Java ClassLoader:同じクラスを2回ロードする

ClassLoader cl = Thread.currentThread().getContextClassLoader(); 
    Class<?> compiledClass = cl.loadClass(stringClass); 

何が欠けていますか?新しいインスタンスのようなものか?

答えて

10

クラスローダーは、既にロードされているクラスを置き換えることはできません。 loadClassは、既存のClassインスタンスの参照を返します。

新しいクラスローダをインスタンス化して、新しいクラスをロードする必要があります。そして、クラスを "置き換える"場合は、このクラスローダーを投げ捨てて別のクラスローダーを作成する必要があります。あなたのコメント(秒)に対応して


ClassLoader cl = new UrlClassLoader(new URL[]{pathToClassAsUrl}); 
Class<?> compiledClass = cl.loadClass(stringClass); 

ような何かを行うことにより同定した(このクラスローダは、「デフォルトの委譲の親であるClassLoader」を使用しますと、あなたが世話をする必要があり、クラス完全修飾クラス名)はロードされておらず、その親クラスローダによってロードできません。したがって、 "pathToClassAsUrl"はクラスパス上にあるべきではありません!

+0

私のメソッドでClassLoaderを置き換えたり削除したりするにはどうしたらいいですか? – ctekk

+0

また、カスタムClassLoaderを作成すると動作しますか? – ctekk

+0

ありがとうございます、あなたのコメントの良い説明をここで見つけました:http://www.exampledepot.com/egs/java.lang/reloadclass.html – ctekk

1

毎回新しいClassLoaderをロードするか、毎回クラスに別の名前を付けてインタフェース経由でアクセスする必要があります。

interface MyWorker { 
    public void work(); 
} 

class Worker1 implement MyWorker { 
    public void work() { /* code */ } 
} 

class Worker2 implement MyWorker { 
    public void work() { /* different code */ } 
} 
+0

同じ方法で毎回新しいClassLoaderを読み込む方法は? – ctekk

+0

'new ClassLoader()'を作成し、defineClassを呼び出してクラスをロードするようにトリガーすることができます。 –

+0

新しいClassloader()をこのように開始することはできません。 – ctekk

0

他の回答よりも基本的な問題だと思います。クラスローダーが、あなたが思うものとは異なるファイルをロードしている可能性が非常に高いです。この理論をテストするには、.classファイル(.javaソースを再コンパイルしないでください)を削除し、コードを実行してください。あなたは例外を取得する必要があります。

例外が発生しない場合は、明らかにクラスローダーが、あなたが思うものとは異なる.classファイルをロードしています。したがって、同じ名前の別の.classファイルの場所を検索してください。その.classファイルを削除して、もう一度やり直してください。実際にロードされている.classファイルが見つかるまで試してください。これを実行したら、コードを再コンパイルしてクラスファイルを正しいディレクトリに手動で置くことができます。

+0

しかし、上記の答えは、クラスが読み込まれると、クラスローダーはファイルから再度読み込まないことを示唆しています。そして、これは適切な行動であるようです。私もそれを理解しました。 – ctekk

関連する問題