이것은 개요 페이지입니다. 자세한 내용은 hotswapagent.org를 방문하세요.
Java 무제한 런타임 클래스 및 리소스 재정의.
이 프로젝트의 주요 목표는 전통적인 "코드 변경 -> 다시 시작하고 대기... -> 확인" 개발 주기의 필요성을 없애는 것이었습니다. 시간이 지남에 따라 이 개념은 Java 생태계 내에서 새로운 패러다임으로 발전하여 실행 중인 애플리케이션 내에서 실시간 소프트웨어 개발이 가능해졌습니다. 이 접근 방식은 Docker 컨테이너와 같은 제한된 환경에서도 가능합니다.
IntelliJ 사용자인 경우 IntelliJ HotSwapHelper 플러그인을 사용하여 HA 및 DCEVM 설정을 단순화할 수 있습니다.
다운로드 및 설치:
Java 17/21의 경우: 최신 JBR17 또는 JBR21을 다운로드하세요. 이러한 버전에는 내장 Hotswap 에이전트가 포함되어 있지 않으므로 hotswap-agent.jar
lib/hotswap
폴더에 수동으로 복사해야 합니다. 여기에서 최신 Hotswap Agent를 찾을 수 있습니다. lib/hotswap
폴더에 있는 파일 이름이 파일 이름에 버전 번호 없이 hotswap-agent.jar
로 지정되어 있는지 확인하세요.
Java 11의 경우: HotswapAgent가 통합된 TravaJDK를 사용하고 이를 대체 JDK로 설치합니다. 또는 TravaJDK에는 내장형 HotswapAgent가 포함되어 있습니다.
Java 8의 경우: HotswapAgent와 함께 jdk8-dcevm을 사용하십시오.
HotswapAgent 모드:
dcevm-11.0.9
부터 HotswapAgent는 기본적으로 비활성화됩니다. 다음 세 가지 모드 중 하나에서 JVM 옵션을 사용하여 HotswapAgent에 대한 지원을 활성화할 수 있습니다.
HotswapAgent=core
모드는 핵심 JVM 플러그인을 제외하고 추가 플러그인 없이 작동하므로 스캔 및 클래스 복사 작업이 줄어들어 성능이 더 빨라집니다. 추가 플러그인을 사용하려면 pom.xml
파일에서 Maven 종속성으로 구성해야 합니다. 반면 HotswapAgent=fatjar
모드에는 기본적으로 모든 플러그인이 포함되어 있어 애플리케이션 시작이 약간 느려질 수 있습니다.
-XX:HotswapAgent=fatjar
내부 fatjar HotswapAgent를 활성화합니다.
-XX:HotswapAgent=core
내부 코어 HotswapAgent를 활성화합니다.
-XX:HotswapAgent=external
HotswapAgent에 대한 JVM 지원을 구성하고 사용자가 -javaagent:
옵션을 사용하여 외부 hotswap-agent.jar
제공할 수 있도록 합니다.
3.실행:
Java17/21: -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar
옵션을 사용하여 애플리케이션을 실행하여 고급 핫스왑(dcevm)을 활성화하고 Hotswap Agent fatjar 릴리스를 사용합니다. 대체 core
또는 external
모드로 fatjar
대신 사용할 수 있습니다.
Java11: Hotswap Agent fatjar 릴리스를 사용하려면 -XX:HotswapAgent=fatjar
옵션을 사용하여 애플리케이션을 시작합니다.
Java8: -XXaltjvm=dcevm -javaagent:hotswap-agent.jar
옵션을 사용하여 애플리케이션을 실행하여 기본 설정을 가져옵니다. 선택적으로 hotswap-agent.properties
애플리케이션에 추가하여 플러그인 및 에이전트 동작을 구성할 수 있습니다.
3. 애플리케이션을 실행합니다.
디버그 모드에서 애플리케이션을 시작하고 에이전트와 플러그인이 올바르게 초기화되었는지 확인하세요.
HOTSWAP AGENT: 9:49:29.548 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent - unlimited runtime class redefinition. HOTSWAP AGENT: 9:49:29.725 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [org.hotswap.agent.plugin.hotswapper.HotswapperPlugin, org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin, org.hotswap.agent.plugin.hibernate.HibernatePlugin, org.hotswap.agent.plugin.spring.SpringPlugin, org.hotswap.agent.plugin.jetty.JettyPlugin, org.hotswap.agent.plugin.tomcat.TomcatPlugin, org.hotswap.agent.plugin.zk.ZkPlugin, org.hotswap.agent.plugin.logback.LogbackPlugin] ... HOTSWAP AGENT: 9:49:38.700 INFO (org.hotswap.agent.plugin.spring.SpringPlugin) - Spring plugin initialized - Spring core version '3.2.3.RELEASE'
4. 재정의 확인
변경된 리소스를 저장하거나 IDE의 HotSwap 기능을 사용하여 변경 사항을 다시 로드하세요.
각 애플리케이션 프레임워크(Spring, Hibernate, Logback 등)에는 클래스 재정의(예: 새 엔터티 클래스가 도입된 후 Hibernate 구성 다시 로드) 후 최신 상태를 유지하기 위해 특별한 다시 로드 메커니즘이 필요합니다. Hotswap 에이전트는 플러그인 시스템으로 작동하며 모든 주요 프레임워크 플러그인과 함께 사전 구성되어 배송됩니다. 애플리케이션의 일부로 사용자 정의 플러그인을 작성하는 것은 쉽습니다.
이 프로젝트는 지원되는 프레임워크와 다양한 버전이 많기 때문에 매우 복잡합니다. 이를 유지하려면 지역 사회 기여가 필수입니다. 애플리케이션 내부에 플러그인을 생성하거나 예제/통합 테스트를 작성하여 시작할 수 있습니다. 문서 개선은 항상 필요합니다 :-). 도움을 주셔서 감사합니다!
향상된 Java 핫스왑 - 메소드 본문 변경, 메소드 추가/이름 변경, 필드 등 ...지원되지 않는 유일한 작업은 슈퍼클래스를 변경하는 것입니다.
디버그 모드에서 IDE의 표준 Java Hotswap을 사용하여 변경된 클래스를 다시 로드할 수 있습니다.
또는 컴파일 후 변경된 클래스를 다시 로드하려면 autoHotswap 속성 -XXaltjvm=dcevm -javaagent:PATH_TO_AGENThotswap-agent.jar=autoHotswap=true
설정하세요. 이 설정을 사용하면 다시 시작하지 않고도 프로덕션 시스템을 다시 로드할 수 있습니다.
자동 구성 - 실행 중인 Java 애플리케이션에 알려진 모든 로컬 클래스 및 리소스가 자동으로 검색되고 다시 로드되는지 감시됩니다(JAR 파일 내부가 아닌 로컬 파일 시스템의 모든 파일).
추가 클래스 경로 - 종속 JAR 내에서 런타임 클래스를 변경해야 합니까? 클래스 파일을 감시하기 위해 extraClasspath 속성을 사용하여 디렉터리를 클래스 경로로 추가합니다.
변경 후 리소스 다시 로드 - webapp 디렉토리의 리소스는 일반적으로 애플리케이션 서버에 의해 다시 로드됩니다. 하지만 src/main/resources와 같은 다른 리소스는 어떻습니까? watchResources 속성을 사용하여 리소스 변경을 감시할 디렉터리를 추가합니다.
프레임워크 지원 - 플러그인 시스템을 통해 많은 프레임워크가 지원됩니다. 새로운 플러그인을 쉽게 추가할 수 있습니다.
빠름 - 플러그인이 초기화될 때까지 리소스를 소비하지 않거나 애플리케이션 속도를 늦추지 않습니다(자세한 내용은 런타임 오버헤드 참조).
문제나 질문이 있는 경우 HotswapAgent 포럼에 문의하세요.
이 프로젝트는 JRebel과 유사합니다. 주요 차이점은 다음과 같습니다.
HotswapAgent(DCEVM)는 Java8, Java11 및 Java17을 지원합니다!
HotswapAgent는 기본 프로젝트 설정을 위해 추가 구성이 필요하지 않습니다.
JRebel은 현재 더욱 성숙해졌으며 더 많은 플러그인을 포함하고 있습니다.
JRebel은 오픈 소스도 아니고 무료도 아닙니다.
JRebel은 다시 로드할 때 모든 클래스의 바이트코드를 수정합니다. 디버깅을 수정하려면 특별한 IDE 플러그인이 필요합니다.
HotswapAgent extraClasspath는 JRebel 구성과 유사합니다.
HotswapAgent가 watchResources 구성을 추가합니다.
HotswapAgentExamples GitHub 프로젝트를 참조하세요. 예제 애플리케이션의 목적은 다음과 같습니다.
복잡한 자동화 통합 테스트(릴리스 전에 다양한 구성 확인, run-tests.sh
스크립트 참조)
플러그인 개발 중(예: 컨테이너 내부) "실제" 플러그인 사용을 확인하기 위해
일반적인 애플리케이션 설정을 위한 작업 솔루션을 제공합니다.
기존 또는 새로운 설정에 대한 문제를 시뮬레이션하는 샌드박스
자유롭게 분기/분기하고 설정을 위한 애플리케이션을 생성하세요(기능적이지만 최대한 간단함). 일반 설정이 마스터에 병합됩니다.
필요하지 않습니다 :) 정말요! 모든 변경 사항은 투명하며 패치+에이전트를 다운로드하고 애플리케이션/애플리케이션 서버를 설정하기만 하면 됩니다. 표준 Java 핫스왑 동작을 사용하므로 IDE가 예상대로 작동합니다. 그러나 우리는 다운로드 및 구성을 돕기 위해 IDE 플러그인을 개발하고 있습니다.
일부 플러그인은 이미 사용 가능합니다:
Intellij의 "디버그" 버튼 옆에 두 가지 작업(핫스왑으로 실행, 핫스왑으로 디버그)을 추가합니다.
작업을 클릭하면 VM 매개변수가 자동으로 설정되므로 VM 매개변수를 수동으로 설정할 필요가 없습니다.
소스 코드 및 문서: https://github.com/gejun123456/HotSwapHelper.
기본 구성은 실행 중인 애플리케이션(클래스로더)이 알고 있는 클래스 경로에서 클래스와 리소스를 다시 로드하도록 설정되어 있습니다. 다른 구성이 필요한 경우 hotswap-agent.properties 파일을 클래스 경로 루트(예: src/main/resources/hotswap-agent.properties
)에 추가하세요.
사용 가능한 속성 및 기본값에 대한 자세한 문서는 에이전트 속성 파일에서 찾을 수 있습니다.
명령줄 옵션의 전체 구문은 다음과 같습니다.
-javaagent:[yourpath/]hotswap-agent.jar=[option1]=[value1],[option2]=[value2]
Hotswap 에이전트는 다음 옵션을 허용합니다.
autoHotswap=true - 모든 .class 파일의 변경 사항을 감시하고 실행 중인 애플리케이션에서 클래스를 자동으로 Hotswap합니다(IDE 디버깅 세션에서 Hotswap을 실행하는 대신).
비활성화Plugin=[pluginName] - 플러그인을 비활성화합니다. 이렇게 하면 플러그인 로드가 완전히 금지됩니다(hotswap-agent.properties의 비활성화Plugin 옵션과 반대). 이 옵션은 클래스로더에 대한 플러그인만 비활성화합니다. 비활성화하려는 모든 플러그인에 대해 이 옵션을 반복할 수 있습니다.
vm 옵션 -Dhotswapagent.disablePlugin=Spring,SpringBoot를 추가하여 플러그인을 비활성화합니다. 이전 섹션의 에이전트 옵션 비활성화Plugin과 동일하게 작동합니다.
Hotswap 에이전트는 리소스 및 프레임워크 구성(Spring, Hibernate 등)을 다시 로드하는 작업을 수행하지만 클래스를 다시 로드하는 것은 표준 Java 핫스왑 메커니즘에 따라 다릅니다. 표준 Java 핫스왑은 메소드 본문 변경만 허용하므로 사실상 사용할 수 없습니다. DCEVM은 핫스왑에서 거의 모든 구조적 클래스 변경을 허용하는 JVM(핫스팟) 패치입니다(계층 구조 변경 제외). hotswap 에이전트는 표준 Java에서도 작동하지만 DCEVM을 사용하는 것이 좋습니다(그리고 모든 자습서에서는 DCEVM을 대상 JVM으로 사용합니다).
Hotswap 에이전트는 플러그인 관리자, 플러그인 레지스트리 및 여러 에이전트 서비스(예: 클래스/리소스 변경 감시)가 포함된 플러그인 컨테이너입니다. 일반적인 작업 및 클래스 로딩 문제에 도움이 됩니다. @Plugin 주석이 달린 클래스의 클래스 경로를 검색하고, 에이전트 서비스를 주입하고, 다시 로드 후크를 등록합니다. 런타임 바이트코드 수정은 javaasist 라이브러리에서 제공됩니다.
Hotswap Agent가 관리하는 플러그인은 일반적으로 특정 프레임워크에 중점을 둡니다. 예를 들어 Spring 플러그인은 HA 서비스를 사용하여 다음을 수행합니다.
Spring 컨텍스트 및 등록된 스캔 경로를 가져오기 위해 루트 Spring 클래스를 수정합니다.
스캔 경로의 리소스 변경 사항을 감시하세요.
스캔 경로 패키지 내 클래스 파일의 핫스왑을 감시하세요.
변경 후 Bean 정의 다시 로드
... 그리고 다른 많은 사람들
CXF-JAXRS(3.x) - 리소스 클래스 재정의 후 JAXRS 리소스를 재정의하고, Spring 및 CDI(Weld/OWB)와 통합된 경우 인스턴스를 다시 주입합니다.
Deltaspike(1.x,2.x) - 메시지, ViewConfig, 저장소, 프록시 다시 로드. Deltaspike 범위의 CDI 빈 재주입.
ELResolver(2.x-5.x)(JuelEL, Appache Commons EL, Oracle EL 3.0) - 클래스 변경 시 ELResolver 캐시를 지웁니다. #{...} 표현식에 대한 핫스왑을 지원합니다.
FreeMarker - 클래스 정의 변경 시 Apache Freemarker Bean 클래스 내부 검사 캐시를 지웁니다.
Hibernate(3.x-6.x) - 엔터티 생성/변경 후 Hibernate 구성을 다시 로드합니다.
iBatis - iBatis 구성을 다시 로드합니다.
IDEA - IDEA에서 IntelliJ IDEA 개발 지원
Jackson - 클래스를 재정의할 때 jackson 내부 캐시를 지웁니다.
Jersey1 - 루트 리소스 또는 공급자 클래스 정의 또는 재정의 후에 Jersey1 컨테이너를 다시 로드합니다.
Jersey2 - 루트 리소스 또는 공급자 클래스 정의 또는 재정의 후에 Jersey2 컨테이너를 다시 로드합니다.
로그백 - 로그백 구성을 다시 로드합니다.
Log4j2 - Log4j2 구성을 다시 로드합니다.
Mojarra(2.x) - 애플리케이션 리소스 번들 변경 사항(속성 파일)을 지원합니다. ViewScoped 빈 재주입/다시 로드를 지원합니다.
MyBatis (5.3) - 매퍼 파일 변경 후 구성 다시 로드
MyFaces(2.x-4.x) - 애플리케이션 리소스 번들 변경 사항(속성 파일)을 지원합니다. ViewScoped 빈 재주입/다시 로드를 지원합니다.
OmniFaces - ViewScoped 빈 재주입/다시 로드를 지원합니다.
OpenWebBeans - (CDI) (1.x-4.x) - 클래스 정의/변경 후 Bean 클래스 정의를 다시 로드합니다. 속성 파일에 정의된 전략에 따라 Bean을 다시 로드할 수 있습니다.
OsgiEquinox - Eclipse 플러그인 또는 Eclipse 플랫폼 개발을 위한 핫스왑 지원.
RestEasy(2.x, 3.x) - 클래스 재정의를 정리하고 등록합니다.
Spring(3.2.x+, 4.x, 5.x) - 클래스 정의/변경 후 Spring 구성을 다시 로드합니다.
Spring Boot(1.5.x+, 2.0.x) - Spring Boot 구성 파일을 실시간으로 동적으로 다시 로드합니다.
Vaadin(23.x, 24.x) - 경로, 템플릿 모델 및 실제로 모든 것을 즉시 업데이트합니다.
WebObjects - 클래스 변경 후 키 값 코딩, 구성 요소, 작업 및 유효성 검사 캐시를 지웁니다.
Weld(CDI)(2.x-5.x) - 클래스 정의/변경 후 Bean 클래스 정의를 다시 로드합니다. 속성 파일에 정의된 전략에 따라 Bean을 다시 로드할 수 있습니다.
Wicket - 속성 파일이 변경되면 Wicket 캐시를 지웁니다.
WildFlyELResolver - 클래스 재정의 후에 BeanELResolver를 지웁니다.
ZK(5x-7x) - ZK 프레임워크(http://www.zkoss.org/). 캐시를 비활성화하고 레이블 캐시 및 Bean 확인자 캐시를 유지 관리하도록 라이브러리 속성 기본값을 변경합니다.
JBossModules - JBoss의 모듈 클래스 로더에 추가 클래스 경로를 추가합니다. (야생파리)
부두 - 앱 클래스로더에 추가 클래스 경로를 추가합니다. WebAppContext.getExtraClasspath를 지원하는 모든 버전이 지원되어야 합니다.
Tomcat(7.x,8.x,9.x,10.x)은 extraClasspath 및 webApp 속성을 사용하여 Apache Tomcat을 구성합니다. GlassFish, Payara 및 Tomee7도 지원합니다.
Undertow - undertow의 리소스 관리자에 추가 클래스 경로, watchResources 및 webappDir을 추가합니다.
Weblogic - 앱 클래스로더에 추가 클래스 경로를 추가합니다.
AnonymousClassPatch - 호환되지 않는 변경을 방지하기 위해 익명 내부 클래스 이름을 교환합니다.
ClassInit - 클래스/열거형 재정의 후 새 정적 멤버/열거형 값을 초기화하고 남아 있는 정적 값을 유지합니다. (알려진 DCEVM 제한 사항 수정)
Hotswapper - JPDA(Java Platform Debugger Architecture)를 통해 클래스 파일 변경 사항을 감시하고 즉시 다시 로드(핫스왑)합니다.
프록시(com.sun.proxy, CGlib 지원) - 변경된 인터페이스 또는 클래스를 구현하거나 확장하는 프록시 클래스를 재정의합니다.
플러그인 프로젝트 기본 README.md 파일에서 각 플러그인에 대한 자세한 문서를 찾아보세요.
사용하는 프레임워크 수와 비활성화된 캐시에 따라 다릅니다. Spring + Hibernate를 기반으로 하는 대규모 실제 엔터프라이즈 애플리케이션에 대한 측정 예시는 Jetty에서 실행됩니다.
Setup | Startup time -----------------------------|------------- Run (plain Java) | 23s Debug (plain Java) | 24s Debug (plain DCEVM) | 28s Agent - disabled all plugins | 31s Agent - all plugins | 35s
애플리케이션의 일부로 플러그인을 직접 작성할 수 있습니다. @Plugin
주석이 달린 클래스를 검색하려면 hotswap-agent.properties
구성 내에 pluginPackages=your.plugin.package
설정하세요. 컴파일하려면 에이전트 JAR 종속성도 필요하지만 애플리케이션에 JAR을 추가하지 않도록 주의하세요. javaagent로만 로드되어야 합니다. 메이븐 의존성:
org.hotswapagent HotswapAgent ${project.version} provided
주석이 달린 간단한 플러그인을 살펴보려면 examplePlugin(TestApplication의 일부)을 참조하세요. 에이전트 개념을 이해하려면 에이전트 Readme를 읽어보세요. 더 많은 예제를 보려면 기존 플러그인 소스 코드를 확인하세요.
기본 디렉터리에서 run-tests.sh
스크립트를 실행합니다. 현재는 JAVA_HOME 위치 디렉터리를 수동으로 설정해야 합니다. 릴리스 전에 DCEVM이 포함된 Java 11 이상을 확인해야 합니다. 모든 자동 테스트는 단일 테스트가 실패할 경우 전체 스크립트가 실패하도록 설정됩니다.
저장소 루트를 나타내는 디렉터리로 이동합니다. DCEVM의 이름이 dcevm
인 경우
mvn release:prepare mvn release:perform
핫스왑 에이전트:
Jiri Bubnik - 프로젝트 코디네이터, 초기 구현
Alexandros Papadakis - Maven 버전 관리, Weld, JSF, Hibernate3, RestEasy, WildFly 플러그인
Erki Ehtla - 스프링 플러그인, 프록시 플러그인
블라디미르 드보락 - ELResolver, OsgiEquinox, Weld, Owb, Deltaspike, Jvm, Jdk, JBossModules, ClassInit, JSF, Mybatis
Sergey Lysenko - 용접 플러그인
Samuel Pelletier - WebObjects 플러그인
Jan Tecl - 웹 디자인
@liuzhengyang - 잭슨 플러그인
Lukasz Warzecha - Log4j2 플러그인
@muwaiwai - iBatis 플러그인
Thomas Heigl - Wicket 플러그인
AJ Banck - FreeMarker 플러그인
Sinan Yumak - Mojarra, MyFaces 플러그인
smallfour - Mybatis 플러그인
@cvictory - Spring 플러그인, Spring Boot 플러그인
@homejim - MyBatis 플러그인, MyBatisPlus 플러그인
DCEVM:
Thomas Würthinger - 초기 구현.
Ivan Dubrov - 전 프로젝트 코디네이터, Java7+Java8 업데이트, 패치, 빌드 시스템(Gradle)
Kerstin Breitender - 기여자.
Christoph Wimberger - 기여자.
Vladimir Dvorak - java9,java11,jbr17,jbr21 마이그레이션, 기여자
Jiri Bubnik - java9,java11 마이그레이션