Java ClassLoader

풀그림 2008. 10. 8. 11:17

. ClassLoader ?

- The Java Classloader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine

- 클래스 로더는 런타임에 클래스 파일을 찾고 로딩하는 임무를 맡는다. 자바에서는 상이한 클래스 로더를 사용하는 것이 가능하며, 커스터마이즈로 클래스 로더를 사용해도 된다. 클래스 파일은 스태틱(static)하게 빌드된 C 프로그램처럼 메모리에 한꺼번에 로드되지 않고 온디맨드 방식으로 로드된다. ClassLoader가 메모리에 올리게 한다.

- .class ClassLoader가 메모리에 올라가는 [Class 객체]로 만드는 것이다. 여기서 주의할 점은 [Class 객체] [일반객체]가 아님을 알아 두어야 한다. [Class객체]를 통해서 [일반객체]들이 생성된다. static변수들도 [Class객체]에 있어서 Global하게 사용이 가능하다. ([일반 객체] Garbage Collection의 대상이 되지만 [Class 객체] Garbage Collection의 대상이 되지 않기 때문이다.)

- 클래스 로더는 클래스들을 Java Virtual Machine (JVM)에 로딩하는 일을 담당한다

. 기능

- 로컬이나 네트웤에 있는 .class .jar파일들을 동적으로 로딩이 가능하다.

(클래스패스로 잡혀 있지 않은 경우에 URLClassLoader 이용해서 동적으로 클래스를 로딩할 있다. 주의할 점들이 있어서 남긴다. URLClassLoader 클래스는 java.net 패키지에 존재한다. 클래스는 클래스들을 URL 기반으로 하여 디스크나 네트워크를 통해서 다이나믹하게 로딩하는 것을 지원해 준다)

(http://cafe.naver.com/lekpro.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=242)

. 종류 와 설명

- Bootstrap class loader,  Extensions class loader, System class loader

The bootstrap class loader loads the core Java libraries, i.e. core.jar, server.jar etc. in the <JAVA_HOME>/lib directory. This class loader, which is part of the core JVM, is written in native code.

The extensions class loader loads the code in the extensions directories (<JAVA_HOME>/lib/ext or any other directory specified by the java.ext.dirs system property). It is implemented by the sun.misc.Launcher$ExtClassLoader class.

The system class loader loads code found on java.class.path, which maps to the system CLASSPATH variable. This is implemented by the sun.misc.Launcher$AppClassLoader class.

(http://en.wikipedia.org/wiki/Java_Classloader)

-

 Bootstrap classLoader는 모든 ClassLoader의 부모 ClassLoader이며,   ClassLoader를 사용해서 standard JDK classes를 로드하게 됩니다.
Extensions ClassLoader
Bootstrap ClassLoader를 상속하며, lib/ext 디렉토리에 있는 클래스를 로드하게 됩니다
.
마지막으로 System-Classpath ClassLoader Extensions ClassLoader를 상속하며, CLASSPATH에 잡혀 있는 모든 클래스, java.class.path 시스템 프라퍼티, -cp 혹은 -classpath에 잡혀 있는 모든 클래스를 로드하게 됩니다
.

OSGi
를 이해하는데 중요한 개념이 ClassLoader이기 때문에 ClassLoader를 조금 살펴봤습니다. 물론 OSGi가 아니더라도 중요한 문제겠죠
.

Crosscutter
님께서
좋은 를 해주셔서 열심히 읽어 봤습니다. 간단히 정리해보면 아래와 같습니다. 자세한 내용은 링크를 직접 읽어보시면 됩니다.

- 규칙 1. 클래스 로더는 계층 구조를 형성
-
규칙 2. 클래스는 필요 시점에 로딩된다.
-
규칙 3. 클래스 A를 로팅할 때는, 클래스 A를 호출한 클래스 B의 클래스 로더가 인스턴스 로딩을 담당한다
.
-
규칙 4. 클래스 유일성 식별: 클래스명+패키지명+클래스로더 인스턴스

-
규칙 5. 클래스 로더에는 명시적인 Unload가 없다. 대신 GC될 때 Unload 된다.

(http://chanwook.tistory.com/622)

. 내용

- 모든 ClassLoader의 입구는 loadClass 메소드가 된다. loadClass를 호출하게 되면 최초로 findLoadedClass라는 메소드를 호출하는데, 이것은 메모리에 Class 객체가 존재하는지 먼저 확인하고 있으면 바로 Class 객체를 반환하게 되고, 없으면 상위 ClassLoader에게 의뢰하게 된다. 이러한 식으로 최상위인 System ClassLoader까지 거슬러 올라가서 메모리를 확인한다. System ClassLoader에서는 findLoadedClass 메소드를 통해서 아무런 Class 객체를 찾을 수 없다면 비로소 findClass 메소드를 호출하게 된다. findClass는 실제로 자신의 Classpath를 뒤져서 해당 .class 파일을 찾게 된다. findClass 메소드 내부에서 .class 파일을 찾게 되면 defineClass라는 메소드를 호출하게 되는데, 이는 protected 메소드이므로 시퀀스 다이어그램에서 표현하지는 않았다. defineClass 메소드는 찾은 .class 라는 자바 바이트 코드 파일을 Class 객체로 변환하는 작업을 하게 된다. 만약 findClass 메소드에서 .class 파일을 찾지 못하면 ClassNotFoundException을 발생시키며 바로 하위 ClassLoader에게 보낸다.

하위 ClassLoader에서는 위에서 수행한 findClass 메소드를 수행한다. 여기서도 발견을 못하면 또 하위로 ClassNotFoundException을 내려 보낸다. 계속해서 최하위까지 내려 갔을 경우 아무 것도 찾지 못했다면, 결국 사용자가 ClassNotFoundException을 받게 되는 것이다.

[출처] ClassLoader 비밀|작성자 asura71

 

- 로드된 클래스를 위해 ClassLoder 의 어떤 인스턴스가 메쏘드를 호출했는지는 매우 중요하다. 그러므로 두 개의 ClassLoder 인스턴스가 동일한 혹은 상이한 소스의 바이트 코드를 정의한다면 정의된 클래스는 다르게 다뤄진다.

. 사용예

// Hello.java
public class Hello {
  public String returnSay() {
    return "Hello World";
  }
}
 
// Hello2.java
import java.lang.reflect.*;
import java.net.*;
 
public class Hello2 {
  public static void main(String[] args) throws Exception {
    if (args.length != 2) {
      System.out.println("Usage: java Hello2 클래스명 메소드명");
      System.exit(0);
    }
    URL[] urlArray =
    {
      new java.io.File("ttr/").toURL()
    };
    Class cls = new URLClassLoader(urlArray).loadClass(args[0]);
    Object obj = cls.newInstance();
    Method method = cls.getMethod(args[1],null);
    String s = (String)method.invoke(obj,null);
    System.out.println(s);
  }
}

[SeparateClassLoaderWithStatic2.
class.getClassLoader()]
null이 들어가면 결과가 true, false가 나온다.

 

. 간단히 dynamic loading하는 소스

- Class type = ClassLoader.getSystemClassLoader().loadClass(name);

Object obj = type.newInstance();

 

. The basics of Java class loaders

http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html

. classloader를 자세히 설명되어 있음

http://blog.naver.com/asura71?Redirect=Log&logNo=30021992124

. URLClassLoader 셈플

http://cafe.naver.com/lekpro.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=242

. Classloader에 대한 기사내용

http://news.naver.com/main/read.nhn?mode=LSD&mid=sec&sid1=105&oid=092&aid=0000008699

. IBM ClassLoader관련 자세한 설명

http://www.ibm.com/developerworks/kr/series/j-dclp.html?ca=dnn-krt-20071226

. auto reload하는 프로그램(Thread.currentThread().setContextClassLoader(classLoader) 사용예)http://blog.naver.com/jjoommnn?Redirect=Log&logNo=130027297615

 

Posted by 파이팅야
,