2017-12-15 16 views
1

私のカスタムクラスローダークラスは次のとおりです。私はこれを以下のjavaargsを持つデフォルトクラスローダーとして設定します。カスタムクラスローダーを使用してロードされたリロードクラス

-Djava.system.class.loader=MyCustomClassLoader 

import java.io.*; 
public class MyCustomClassLoader extends ClassLoader { 
    public MyCustomClassLoader() { super(); } 
    public MyCustomClassLoader(ClassLoader parent) { super(parent); } 
    protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { 
     Class c = super.loadClass(name, resolve); 
     System.out.println("name: " + name + ", class: " + c); 
     return c; 
    } 
} 

この時点では、サーバーを起動すると、すべてのクラスに上記のカスタムクラスローダークラスがロードされます。必要に応じて、特定のパッケージ(com.testなど)の一部であるクラスのクラス定義を更新/再読み込みしたいと考えています。どうしたらいいですか?

答えて

0

custorクラスを単独でロードするクラスローダを作成してください。スーパーロードすることはできません。私の例を試してみてください。理解するのに役立つかもしれません。

package test; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.util.HashMap; 
import java.util.Map; 

class MyClassLoader extends ClassLoader { 
    private Map<String, Class<?>> loadedClasses = new HashMap<>(); 
    private String dir; 

    public MyClassLoader(String dir) throws MalformedURLException { 
     this.dir = dir; 
    } 

    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 
     Class<?> c = findLoadedClass(name); 
     if (c != null) { 
      return c; 
     } 
     c = loadedClasses.get(name); 
     if (c != null) { 
      return c; 
     } 
     try { 
      String path = dir + name.replace(".","/") + ".class"; 
      byte[] bytes = Files.readAllBytes(Paths.get(path)); 
      c = defineClass(name, bytes, 0, bytes.length, null); 
      if (resolve) { 
       resolveClass(c); 
      } 
      return c; 
     } catch (IOException ex) { 
      return super.loadClass(name, resolve); 
     } 
    } 
} 

public class ChildFirstClassLoader { 

    public static void main(String[] args) throws Exception { 
     ClassLoader cl1 = new MyClassLoader("target/classes/"); 
     Object x1 = cl1.loadClass("test.X1").newInstance(); 
     System.out.println(x1.getClass().getClassLoader()); 
     cl1 = null; 

     ClassLoader cl2 = new MyClassLoader("target/classes/"); 
     x1 = cl2.loadClass("test.X1").newInstance(); 
     System.out.println(x1.getClass().getClassLoader()); 

    } 
} 
+0

既存の 'URLClassLoader'よりも' MyClassLoader'の利点はありません。答えのポイントは、1つのクラスローダー内のリロードクラスが機能しないため、2つのクラスローダーインスタンスを作成することです。冗長クラスローダの実装で関連する点から注意をそらすのではなく、それに焦点を当てることをお勧めします。 – Holger

関連する問題