java class loader #2

Language/JAVA 2016. 8. 4. 15:07

ClassLoader 2

 

  // src/java/lang/ClassLoader.java
  public abstract class ClassLoader {
      /*
       * The parent class loader for delegation.
       */
      private ClassLoader parent;
      
      protected synchronized Class loadClass(String name, boolean resolve)
      throws ClassNotFoundException
      {
          // First, check if the class has already been loaded
          Class c = findLoadedClass(name);
          if (c == null) {
              try {
                  if (parent != null) {
                      c = parent.loadClass(name, false);
                  } else {
                      c = findBootstrapClass0(name);
                  }
              } catch (ClassNotFoundException e) {
                  // If still not found, then call findClass in order
                  // to find the class.
                  c = findClass(name);
              }
          }
          if (resolve) {
              resolveClass(c);
          }
          return c;
      }
      ....
  }

코드 4.


코드 4 JDK1.3 ClassLoader 클래스로서 부모 클래스로더로부터 먼저 클래스 로딩을 요청하고그것이 실패할 경우에 직접 클래스를 로딩합니다여기서 부모 클래스가 어떻게 결정되는 지를 보면 JDK 1.3 ClassLoader 클래스는 다음과 같은  개의 생성자를 갖고 있습니다.

  protected ClassLoader(ClassLoader parent) {
      SecurityManager security = System.getSecurityManager();
      if (security != null) {
          security.checkCreateClassLoader();
      }
      this.parent = parent;
      initialized = true;
  }
  protected ClassLoader() {
      SecurityManager security = System.getSecurityManager();
      if (security != null) {
          security.checkCreateClassLoader();
      }
      this.parent = getSystemClassLoader();
      initialized = true;
  }

코드 5.

코드 5 보면부모 클래스로더를 지정하지 않을 경우에는 시스템 클래스로더를 부모 클래스로더로 지정하고 있습니다커스텀 클래스로더에서 부모 클래스로더를 지정하기 위해서는 코드 6 같이 하면 됩니다.

  public class JarFileClassLoader extends ClassLoader {
     public JarFileClassLoader () {
        super(JarFileClassLoader.class.getClassLoader());
        // 
다른 초기화 관련 사항
     }
     ....
     public Class findClass(String name) {
        // 
지정한 클래스를 찾는다.
     }
  }

코드 6.


모든 클래스는  클래스에 해당하는 Class 인스턴스를 가지고 있습니다 Class 인스턴스의 getClassLoader() 메소드를 통해서  클래스를 로딩한 클래스로더를 구할  있습니다코드 6에서는 JarFileClassLoader 클래스를 로딩한 클래스로더를 JarFileClassLoader 클래스로더의 부모 클래스로더로 지정하는 것입니다. 
JVM
에서 부모 클래스로더를 갖지 않은 유일한 클래스로더는 부트스트랩 클래스로더로서 부트스트랩 클래스로더는 자바 런타임 라이브러리에 있는 클래스를 로딩하는 역할을 맡고 있으며항상 클래스로더 체인의   번째에 해당합니다. Java에서는 같은 클래스일지라도다른 클래스로더에 의해서 로딩되었다면 다른 클래스로 구분이 됩니다.

 

Example


  public class ToolsJarLoader extends URLClassLoader {

private static ToolsJarLoader mInstance;

public static ToolsJarLoader getInstance() {

if(mInstance == null) {

mInstance = new                ToolsJarLoader(((URLClassLoader)ClassLoader.getSystemClassLoader()).getURLs());

}

return mInstance;

}


    public ToolsJarLoader(URL[] urls) {

        super(urls);

    }

    

    @Override

    public void addURL(URL url) {

        super.addURL(url);

    }

    

    public boolean isLoaded(URL url) {

     URL[] urls = getURLs();

     for(URL temp : urls) {

     if(temp.equals(url)) {

     return true;

     }

     }

     return false;

    }

}

코드 7.

코드 7 원하는 클래스  jar 런타임에 동적으로 로드하기 위한 클래스 로더이다. addURL 통해 jar  클래스를 로딩한다.


URL jarUrl = new File(toolsJarPath).toURI().toURL();

if(!ToolsJarLoader.getInstance().isLoaded(jarUrl)) {

ToolsJarLoader.getInstance().addURL(jarUrl);

}

Class cls = ToolsJarLoader.getInstance().loadClass("package.ClassName");

Object obj = cls.getConstructor(String.class).newInstance(arg1);

Method method = obj.getClass().getMethod("methodName");

method.invoke(obj);

코드 8.

코드 8 특정 위치에 있는 jar  클래스를 코드 7 있는 클래스로더를 이용하여 런타임에 동적으로 로딩하도록 한다로딩  해당 클래스를 만든다.

 

 

References

 

[1] http://javacan.tistory.com/3

[2] http://blog.naver.com/PostView.nhn?blogId=choigohot&logNo=40192701035

[3] http://javacan.tistory.com/entry/2

: