JRebel은 Javassist 또는 바이트 코드 조작을 사용합니까? 나는 이것을 순수한 관심으로 만 요구하고 있는데 실제로 알 필요는 없다.JRebel은 어떻게 작동합니까?
답변
JRebel은 클래스 재 작성 (ASM과 Javassist)과 JVM 통합을 사용하여 개별 클래스를 버전 화한다. 또한 애플리케이션 서버와 통합되어 클래스/자원 및 웹 서버 조회를 다시 작업 영역으로 리디렉션합니다. 또한 대부분의 앱 서버 및 프레임 워크와 통합되어 변경 사항을 구성 (메타 데이터 또는 파일)에 전달합니다. 그것은 그것의 부족합니다. 오랫동안 개발하고 지원하기 위해 10 명의 세계적 수준의 엔지니어가 필요하며 우리의 상업적 비밀입니다.
Dave Booth의이 주제에 대한 훌륭한 기사입니다. Reloading Java Classes: HotSwap and JRebel — Behind the Scenes.
이것은 내가 가장 많이 읽은 JRebel works의 Simon, ZT Technical Evangelist에 의한 추론입니다.
여기에 내용을 붙여 넣기 :
Jrebel 악기 애플리케이션과 JVM 클래스를 간접 레이어를 만들 수 있습니다. 응용 프로그램 클래스가로드되는 경우 그림 2와 같이 모든 메서드 본문에 런타임 리디렉션 서비스를 사용하는 리디렉션이 있습니다.이 서비스는 다시로드되는 각 버전에 대해 만들어진 익명 내부 클래스를 사용하여 클래스 및 메서드 버전을 관리하고로드합니다. 예를 살펴 보겠습니다.
public class C extends X {
int y = 5;
int method1(int x) {
return x + y;
}
void method2(String s) {
System.out.println(s);
}
}
클래스 C를 처음로드 할 때 JRebel이 클래스를 인스트루먼트합니다. 이 클래스의 시그니처는 동일하지만 메서드 본문이 리디렉션되고 있습니다. 로드 된 클래스는 지금과 같이 보일 것이다 : 우리는 호출하는 객체를 전달, 리디렉션 호출에
public class C extends X {
int y = 5;
int method1(int x) {
Object[] o = new Object[1];
o[0] = x;
return Runtime.redirect(this, o, "C", "method1", "(I)I");
}
void method2(String s) {
Object[] o = new Object[1];
o[0] = s;
return Runtime.redirect(this, o, "C", "method2", "(Ljava/lang/String;)V");
}
}
을, 호출 된 메서드에 매개 변수, 우리의 클래스 이름, 우리의 방법은 이름과 유형 매개 변수와 반환.
public abstract class C0 {
public static int method1(C c, int x) {
int tmp1 = Runtime.getFieldValue(c, "C", "y", "I");
return x + tmp1;
}
public static void method2(C c, String s) {
PrintStream tmp1 =
Runtime.getFieldValue(
null, "java/lang/System", "out", "Ljava/io/PrintStream;");
Object[] o = new Object[1];
o[0] = s;
Runtime.redirect(tmp1, o, "java/io/PrintStream;", "println","(Ljava/lang/String;)V");
}
}
이의 지금은 사용자가 새로운 방법 Z()를 추가하고 호출하여 클래스 C를 변경한다고 가정 해 봅시다 : JRebel은 처음 버전 0이 이제 그 모습을 보자, 특정 버전에 구현과 클래스를로드 그것 method1에서. 클래스 C는 이제 다음과 같습니다
public class C {
int y = 5;
int z() {
return 10;
}
int method1(int x) {
return x + y + z();
}
...
}
다음에 실행 시간이 클래스를 사용 JRebel 컴파일 및 파일 시스템에 된 새로운 버전이 발견, 그래서 C1, 새 버전을로드합니다. 이 버전에는 메소드 z에 대한 추가 메소드와 메소드 1에 대한 갱신 된 구현이 있습니다.
public class C1 {
public static int z(C c) {
return 10;
}
public static int method1(C c, int x) {
int tmp1 = Runtime.getFieldValue(c, "C", "y", "I");
int tmp2 = Runtime.redirect(c, null, "C", "z", "(V)I");
return x + tmp1 + tmp2;
}
...
}
Runtime.redirect 호출
은 항상 새로운 C를 호출, 클래스 C의 최신 버전으로 연결됩니다(). 나중에 코드 변경 전 15 및 25을 반환 방법 항목 (10). 이 구현은 많은 세부 사항과 최적화를 놓치지 만 아이디어를 얻습니다.출처 : http://zeroturnaround.com/rebellabs/why-hotswap-wasnt-good-enough-in-2001-and-still-isnt-today/
@Jevgeni Kabanov : 최종 클래스로 다시로드 처리 JRebel합니까? – Dexter
@Dexter –