라고 하기까진 뭐하고...
그냥 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디렉토리로 모니터링 대상이 되는 클래스들을 모두 옮긴 후
자기가 정의한 클래스로더로 그 클래스들을 전부 로딩한다고 한다. 겉으로 보기엔 상당히 엣지 있는데
속으로는 저런 일을 하고 있었다는 거.... ㅎㅎ
암튼...
세련스럽지는 않지만
해보고 싶은건 결국 해봤다 -_-;;;
근데 난 왜 이걸 그렇게 해보고 싶어했던걸까....-_-ㅋ
그냥 classloader를 바꿔버리는 것을 이용해서 해보았다.
예전에 실패했을 때의 원인이었던것...
(http://devyongsik.tistory.com/274)
기본적으로 클래스패스에 있던 클래스는
이미 시스템클래스로더가 클래스를 로딩한 상태이기 때문에
그 하위 클래스로더에서 아무리 URLClassLoader를 사용해 바꿔치기 해봤자
영향이 없다는 것...
그렇다면, 방법은..
우리가 hot deploy를 해보고 싶은 클래스를 시스템 클래스로더가 아닌
우리가 정의한 (즉, 우리가 컨트롤 할 수 있는) 클래스로더가 물고 올라가도록 하면
이후에도 우리가 컨트롤 할 수 있지 않을까... 생각했다.
이클립스에서 workspace를 c: 쪽을 사용하고 있는데
일단 이런저런 생각하기가 귀찮아서..
그냥 hot deploy의 대상이 되는 BaseDomain이라는 클래스를
d: 드라이브에 넣고, URLClassLoader를 사용해서 그 클래스를 로딩하도록 구현해봤다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Reloader { | |
private Log logger = LogFactory.getLog(Reloader.class); | |
URLClassLoader appClassLoader = null; | |
File dir = new File("d:/"); | |
public void run() throws Exception { | |
URL url = dir.toURL(); | |
URL[] urls = new URL[]{url}; | |
while(true) { | |
Thread.sleep(2000); | |
this.appClassLoader = new URLClassLoader(urls); | |
//Thread.currentThread().setContextClassLoader( this.appClassLoader ); | |
Class appClass = this.appClassLoader.loadClass("BaseDomain"); | |
Method printName = appClass.getMethod("printName", null); | |
Object appInstance = appClass.newInstance(); | |
System.out.println(appInstance); | |
printName.invoke(appInstance, null); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Main { | |
private Log logger = LogFactory.getLog(Main.class); | |
public static void main(String[] args) throws Exception { | |
Reloader reloader = new Reloader(); | |
reloader.run(); | |
} | |
} |
이렇게 실행하면 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디렉토리로 모니터링 대상이 되는 클래스들을 모두 옮긴 후
자기가 정의한 클래스로더로 그 클래스들을 전부 로딩한다고 한다. 겉으로 보기엔 상당히 엣지 있는데
속으로는 저런 일을 하고 있었다는 거.... ㅎㅎ
암튼...
세련스럽지는 않지만
해보고 싶은건 결국 해봤다 -_-;;;
근데 난 왜 이걸 그렇게 해보고 싶어했던걸까....-_-ㅋ