본문 바로가기

WEB개발

[WEB개념] Class Loader & Hot Deploy

Class Loader란?

Class Loader는 자바 바이트코드를 읽어들여 클래스 객체를 생성하는 역할을 담당한다. 

 

클래스 로딩 방식에는 load-time dynamic loading과 run-time dynamic loading이 있다.

load-time dynamic loading은 클래스를 로딩하는 과정에서 다시 필요한 클래스를 로딩한다. 예를 들어 HelloWorld 클래스 내에 System.out.println이 있다면 java.lang.System을 로딩할 것이다.

 

run-time dynamic loading은 클래스 내 코드를 실행하는 과정에서 필요한 클래스를 로딩한다. Class.forName()을 사용하는 경우가 대표적이다.

 

클래스 로딩의 순서는?

  1. Bootstrap Class Loader는 JVM이 초기화 시 필요한 클래스(jre/lib/rt.jar 등)를 로딩한다.
  2. Extension Class Loader는 $JAVA_HOME/jre/lib/ext내 클래스를 로딩한다. (Bootstrap과 Extension을 묶어 Bootstrap으로 표현하는 경우도 있다)
  3. System Class Loader는 애플리케이션이 사용하는 클래스를 로딩한다.

여기까지는 일반적인 자바 애플리케이션의 클래스 로딩이다. 만약 웹로직과 같은 애플리케이션 서버를 사용하는 경우 ServletContainerClassLoader나 ServletContextClassLoader 등이 추가로 존재하게 된다.

자바 스펙에 의해 Class Loader는 다음 조건을 충족해야 한다.

  1. WEB-INF/lib보다 WEB-INF/classes를 먼저 로딩해야 한다. (의무사항)
  2. war 파일 내부의 클래스를 컨테이너 레벨의 jar 파일보다 먼저 로딩한다. (권고사항)

 

톰캣 클래스로딩

 

자바는 매커니즘 상 parent-first & child-last 방식에 의하여 Class Loading한다. 그러나 일부 애플리케이션 서버는 이와 다르게 동작하기도 한다. 예를 들어 톰캣은 마치 parent-last & child-first 방식으로 Class Loading하는 것처럼 보인다. 컨테이너 레벨(톰캣은 Common이라고 표현)보다 애플리케이션 하위를 먼저 로딩하기 때문이다.

  1. Bootstrap
  2. WEB-INF/classes
  3. WEB-INF/lib
  4. System
  5. $CATALINA_BASE/lib 하위의 unpacked 클래스
  6. $CATALINA_BASE/lib 하위의 jar
  7. $CATALINA_HOME/lib 하위의 unpacked 클래스
  8. $CATALINA_HOME/lib 하위의 jar

만약 기존 자바 매커니즘대로 로딩하려면 <Loader delegate="true"/> 설정을 통해 강제 재조정할 수 있다.

  1. Bootstrap
  2. System
  3. $CATALINA_BASE/lib 하위의 unpacked 클래스
  4. $CATALINA_BASE/lib 하위의 jar
  5. $CATALINA_HOME/lib 하위의 unpacked 클래스
  6. $CATALINA_HOME/lib 하위의 jar
  7. WEB-INF/classes
  8. WEB-INF/lib

톰캣에서 System Class Loader에 의해 로딩되는 클래스는 다음과 같다.

  • $CATALINA_HOME/bin/bootstrap.jar
  • $CATALINA_HOME/bin/tomcat-juli.jar (만약 $CATALINA_BASE/bin/tomcat-juli.jar가 존재한다면 이것을 로딩함)
  • $CATALINA_HOME/bin/commons-daemon.jar (존재 시)

톰캣, JDK 8에서 System.getProperty("sun.boot.class.path"); 로 확인한 결과는 다음과 같다.

 

Hot-deploy

 

Hot Deploy란 서버의 재시작 없이 응용프로그램의 동적 변경을 바로 적용 시키는 기능이다.

Hot Deploy를 사용하면, 배치에서 테스트까지의 기간을 줄일 수 있으며, 어플리케이션의 오류로 시스템의 장애 발생 시 단 시간 내에 조치가 가능한 장점이 있습니다

 

WAS를 리부팅하지 않고도 애플리케이션을 deploy 혹은 redeploy할 수 있다. 이것은 System classloader는 리부팅 시에만 가능하다는 기존의 개념을 극복한 것이다. (System classloader는 CLASSPATH에 의해 설정된 클래스를 로딩하는 로더이다) 이것을 Hot-deploy라 부른다.

 

단, System Classloader로 deploy한 클래스는 Hot-deploy할 수 없다. Hot-deploy는 System classloader로부터 상속받은 child classloader들을 사용하여 구현한다. 이것을 Application classloader라 부르기도 한다.

Redeploy는 실제 클래스가 변하는 것이 아니다. 다만 기존 classloader를 새로운 classloader로 변경하는 것 뿐이다.

 

 

Tomcat Hotdeploy

 

1. JAR 다운

https://mvnrepository.com/artifact/org.springframework/springloaded/1.2.8.RELEASE

 

2. tomcat lib 경로에 추가

ex) C:\apache-tomcat-8.5.69\apache-tomcat-8.5.69\lib

 

3. tomcat 설정

modules tab으로 들어가서 Edit 후 Auto Reloading Enabled 해제를 한다. 

 

4. Open launch configuration에 Arguments에 다음을 추가한다.

 

-javaagent:C:\설치경로\springloaded-1.2.8.RELEASE.jar -noverify

 

 

참조

https://sarc.io/index.php/java/473-2016-05-31-15-48-27

https://sarc.io/index.php/miscellaneous/463-2016-05-25-16-26-51

https://oingdaddy.tistory.com/33