본문 바로가기

Java

[JAVA] 클래스 hot deploy #2

라고 하기까진 뭐하고...
그냥 classloader를 바꿔버리는 것을 이용해서 해보았다.

예전에 실패했을 때의 원인이었던것...
(http://devyongsik.tistory.com/274)

기본적으로 클래스패스에 있던 클래스는
이미 시스템클래스로더가 클래스를 로딩한 상태이기 때문에
그 하위 클래스로더에서 아무리 URLClassLoader를 사용해 바꿔치기 해봤자
영향이 없다는 것...

그렇다면, 방법은..
우리가 hot deploy를 해보고 싶은 클래스를 시스템 클래스로더가 아닌
우리가 정의한 (즉, 우리가 컨트롤 할 수 있는) 클래스로더가 물고 올라가도록 하면
이후에도 우리가 컨트롤 할 수 있지 않을까... 생각했다.

이클립스에서 workspace를 c: 쪽을 사용하고 있는데
일단 이런저런 생각하기가 귀찮아서..
그냥 hot deploy의 대상이 되는 BaseDomain이라는 클래스를
d: 드라이브에 넣고, URLClassLoader를 사용해서 그 클래스를 로딩하도록 구현해봤다.




이렇게 실행하면 d: 에 있는 BaseDomain.class를 물고 올라간다.

이제, 다른 프로젝트던 어디서든..BaseDomain.java의 내용을 바꾸고
컴파일 한 후 위 Main이 돌고 있는 상태에서 새로 컴파일한 class를 D:에 넣어주면
새롭게 컴파일 된 내용으로 콘솔에 내용이 찍힌다.

오호라..~ 이게 되네?

하지만, 이걸 실제 어떻게 구현해서 써보려고 하면..
클래스로더가 하나의 클래스를 로딩하고 있는 상태도 아니고..
클래스가 바뀔 때마다 클래스로더 전체를 내렸다가 다시 생성하고 클래스를 다시 로딩하는 것은
상당히 비효율적이라는 생각이 좀 든다.. .. 아니 비효율이 문제가 아니라 다른 클래스들은 어떻게 되는겨..

그래서 다른 사이트에서 보면
URLClassLoader를 상속받아
새롭게 ClassLoader를 정의해서 .class의 바이트코드를 읽어와
defineClass() 메서드를 사용해서 그 클래스만 다시 로딩하는 방법으로 구현 된 것도 있었다.
(http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html)

처음 위 내용 봤을 때는 저렇게까지 해야하나 싶었는데..
생각해보니 안 그럼 낭비가 좀 있을 것 같다...

eclipse4j님이 알려주신 jrebel의 작동 방식도
자기만의 work디렉토리로 모니터링 대상이 되는 클래스들을 모두 옮긴 후
자기가 정의한 클래스로더로 그 클래스들을 전부 로딩한다고 한다. 겉으로 보기엔 상당히 엣지 있는데
속으로는 저런 일을 하고 있었다는 거.... ㅎㅎ

암튼...
세련스럽지는 않지만
해보고 싶은건 결국 해봤다 -_-;;;

근데 난 왜 이걸 그렇게 해보고 싶어했던걸까....-_-ㅋ