https://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html
1. build.gradle 파일의 의존관계 설정 (spring-boot-devtools)
compile('org.springframework.boot:spring-boot-devtools')
2. 인텔리J 설정(Ctrl + Alt + S)
Settings > Build, Execution, Deployment > Compiler 메뉴에서 Build project automatically 체크
3. Registry 값 변경
Ctrl + Alt + Shift + /
를 누르면 나오는 메뉴에서 Registry 를 선택하고 아래와 같이
compiler.automake.allow.when.app.running 레지스트리 값을 true로 변경(체크 하면 됨)
4. 인텔리J 를 재부팅 하고 확인해보기
--- 추가 내용 ---
잘 안 되길래 좀 헤멨다가 다시 정리한 글.
Spring Boot Hot swap using spring-devtools with intelliJ
Description
어플리케이션이 실행 중인 상태에서 클래스 파일이나 정적 자원들을 수정할 경우, 매번 서버를 재시작해주어야 하는 불편함이 있는데, 개발 단계에서는 hot swap 을 적용하여 시간을 아낄 수 있음
Process
IntelliJ 설정
Settings > Build, Execution, Deployment > Compiler 에서 “Build project automatically” 옵션에 체크 후 OK
Ctrl + Shift + Alt + / 를 타입하면 Registry 를 조회/편집할 수 있는 메뉴가 나온다. Registry 를 눌러서 compiler.automake.allow.when.app.running 키 값을 찾아서 체크해준다.
Rerun IntelliJ
Spring Boot 설정
dependencies 추가
compile('org.springframework.boot:spring-boot-devtools')
application.yml (또는 application.properties)에 속성 값 설정
spring.devtools.livereload.enabled=true
spring.devtools.restart.enabled=true
spring.thymeleaf.cache=false
스프링 부트 어플리케이션 실행 방법
gradle bootRun 으로 해도 스프링 부트 어플리케이션은 실행되지만 hot swap은 적용이 안 되었음
따라서 hot swap을 적용시키고 싶으면 main() 메소드를 갖는 main class를 실행해주어야 함. main class를 실행시키면 잘 되는 것을 확인했음.
2019-02-19 추가 내용
Class Hotswap 이 잘 안 된다는 제보를 보고 저도 다시 삽질을 좀 해봤습니다.
아래의 몇줄로 요약하니, 도움이 되기를 바랍니다.
1. spring.devtools.restart.enabled=false 로 설정
2. IntelliJ Run/Debug Configuration 에서 On 'Update' action : "Hot swap classes and update trigger file if failed" 및 on frame deactivation : "Update classes and resources" 지정
3. 스프링 부트 앱을 디버그 모드로 실행
4. 클래스 코드 수정 후, 브라우저(또는 IntelliJ가 아닌 다른 window)를 클릭하면 on frame deactivation 에 지정한 동작이 실행됩니다. 이 때, 클래스가 변경되면 reload 할거냐고 묻는 dialog 가 뜨는데, "다시 묻지 않기"에 체크를 한 후 "Yes"를 선택하시면 그 다음부터 컴파일/빌드/hotswap이 되는 몇초만 기다리면 Container 재기동 없이 변경된 class가 실행됩니다.
이 때, on frame deactivation 이 아니라 on 'Update' action 에 지정한 동작을 발동시키기 위해서는 "Ctrl + F10" 의 키맵이 할당된 "Run" > "Update XXXApplication application" 을 클릭하면 되고, 디버그 모드일 경우에는 "Run" > "Reload changed classes" 메뉴가 활성화 되어 있으므로 이걸 실행시켜도 됩니다.
사실, 아까 On 'Update' action : "Hot swap classes and update trigger file if failed" 의 설정을 하였기 때문에, "Run" > "Update XXXApplication application" 자체가 "Run" > "Reload changed classes" 에 대한 alias 가 되었다고 볼 수 있습니다.
비밀댓글입니다
도움이 되었다니 기쁩니다. 피드백 감사합니다.
비밀댓글입니다
spring dev tools의 경우엔 리소스에 대해서만 핫 스왑이 적용되고, 클래스의 경우엔 오토 리스타트가 되요. 클래스 핫 스왑에 대해선 스프링 로디드(spring loaded)에 대해 알아보세요.
와 감사합니다!!! 정말 도움 많이 되었어요:)
도움이 되셨다니 다행입니다!
도움 많이 됬어요! 감사합니다
댓글 감사합니다. ㅎㅎ
IntelliJ + SpringBoot 2.1.x + Gradle 진행중인데 본문대로 했는데 아무리 해도 자바클래스 수정 후엔 컨테이너가 재기동 되면서 맵핑도 먹통이 되버리더군요. 수정한 부분 핫스왑 역시 안되고..
혹시 저랑 같은 증상이신 분은 그냥
application.yml 설정을
spring:
--devtools:
---livereload:
----enabled: true
---restart:
----enabled: false
--thymeleaf:
---cache: false
위와 같이 해주고 (restart false!) 클래스 파일 수정한다음에 Ctrl+Shift+F9 로 재컴파일 후 클래스 리로드 하면 자동 핫스왑은 아니라도 수동 핫스왑은 되실겁니다;
오 보충 설명 감사합니다. devtools 라는 모듈 특성상 스프링의 코어 모듈들이랑 호환이 안 맞는 부분도 있고, ide에서 실행하는 것과 os에서 gradle bootrun 하는 것의 실행 환경(파라미터 등등)이 조금씩 다르기 때문에 기대하는 액션이 안 나올 경우 하나씩 하나씩 확인이 필요한 것 같습니다. spring loaded가 클래스 핫스왑은 잘 됐던 기억이 있는데 어떤 분들은 한 프로젝트에서 devtools와 spring loaded 함께 쓰시기도 하더라고요. devtools가 가끔 특정 프로덕션 런타임환경에서 문제를 일으키는 경우도 있는 점 등 유의해야할 게 많은 것 같습니다.
저도 다시 한 번 삽질을 해봐야겠네요 ㅎㅎ
spring:
devtools:
livereload:
enabled: true
요렇게만 설정하니까 톰캣이 자동 restart 하면서 Condition evaluation unchanged 라는 메시지 뜨고 클래스 수정 사항이 별도 재컴파일 없이 반영되네요. 회사에서는 이렇게 되는데..
집에서는 톰캣 restart 되고나서 url 이 안먹는.. 뭔가 환경설정 싱크를 잘못 해둔듯 ㅜㅜ
안녕하세요?
Nice 한 방법은 아니지만 저도 다시 조금의 삽질을 해봤습니다.
처음 DK 님께서 말씀하신 것처럼 완전 hotswap 이 잘 안 되더라고요.
IntelliJ 2018.3
Spring boot 2.0.5.RELEASE 버전
이구요.
첫번째 방법 - 수동 hotswap
1. spring.devtools.restart.enabled=false 설정 (컨테이너 자동 재시작 방지)
2. IntelliJ 에서 스프링 부트 앱을 디버그 모드로 실행(Shift + F9) java 클래스 코드 수정
3. Run > Reload changed classes 클릭
(저는 Ctrl + Shift + F5 키맵 할당)
두번째 방법 - 자동 hotswap (반자동?)
1. spring.devtools.restart.enabled=false 설정 (컨테이너 자동 재시작 방지)
2. Run/Debug Configurations 에서 On frame deactivation 항목에 "Update classes and resources" 를 선택
3. 스프링 부트 앱을 디버그 모드로 실행 후 java 클래스 코드 수정
4. 브라우저 클릭 (intelliJ frame 을 비활성화) : 이 순간에 재컴파일/빌드가 수행 됨
5. Reload Changed Classes for XXXApplication 다이얼로그가 뜨는데, "Do not show this dialog in the future" 에 체크한 후 "Yes" 선택
이렇게 정리할 수 있을 것 같습니다.
핵심은 devtools.restart 를 끄고 디버그 모드로 실행시키는 것인 것 같습니다.
Edit Configurations 메뉴에서 보시면 "On 'Update' action" 항목과 "On frame deactivation" 항목 가장 오른쪽에서 툴팁을 보실 수 있는데요.
"Hot swap classes and update trigger file if failed" 라는 항목 아래에
"In debug mode" vs "Otherwise" 로 구분되어 있기도 합니다.
debug 모드로 실행시키면 trigger 파일 지정 없이 모든 파일에 대해서 변경이 감지되면 hot swap 을 시도하도록 되어있네요.
DK님 말씀대로 ctrl+shift+f9로 재컴파일하는 방법은.. devtools 의존성 받지 않은상태, 그리고 application.properties 설정을 안했을때도 되는 방법이네요... (hot swap관련해서 아무 설정안하고 인텔리제이 설치하자마자 바로 사용해도 가능한 방법;;)
hot swap이 가능할려면 코드 수정 후 브라우저에서 새로고침 누르면 바로 수정된 코드가 반영되야 할것같은데요 이게 인텔리제이에서 안되네요
intellij 정적 리소스 reload가 안되서 너무 불편합니다... (css, html 코드 수정)
뭐처럼 intellij 넘어왔는데 이것 때문에 몇일째 삽질중이고 구글링하면서 10번은 계속 해본거 같은데 적용이 안 되고 있습니다...
위 글에 처음부터 추가내용까지 적용해봤는데 reload가 안 되고 있습니다.
일단 sts로 작업하고 있어야겠습니다... 혹시 팀뷰어로 한번 봐주시면 안될까요ㅠ.ㅠ??
혹시 뷰 템플릿 엔진으로 타임리프 말고 다른 거 쓰시는 건 아니신가요?
Handlebars(hbs)사용하고 있습니다. 아 이것때문에 안되는걸까요??
springboot로 처음 개발해 보고 있는데 jsp만 사용해봤습니다... 타임리프를 사용하면 정적 리소스 reload 되나요?!
cache 가 켜져있을 가능성이 있을 것 같아요. 글 본문에는 thymeleaf.cache=false 로 되어있는데 핸들바에 맞게 handlebars.cache=false(?) 같은 형식의 설정으로 바꿔서 사용하시면 안 되는 원인의 가능성을 하나 줄이실 수 있을 것 같아요.
덕분에 적용했습니다 ㅠ.ㅠ!!!!! 감을 못 잡고 있었는데 어딜 봐야 할지 알려주셔서 잘 적용이 됬습니다. 감사합니당~!
적용하셨다니 다행입니다. 알려주셔서 감사합니다.
핫스왑 관련해서 어제부터 검색했었는데 이제야 문제해결 시켜주는 글을 발견했네요...감사합니다.
bootRun 왜 아무도 안알려주는거햐 . . ㅠ !
덕분에 한시간헤멘거 알아갑니다!
SpringBoot DevTools의 livereload 기능을 제대로 못쓰고 있었는데, 덕분에 해결했습니다.
감사합니다.
저는 js 파일이 compile 이 안되서 고생했는데요
결과적으로는 Resource patterns 에(Setting -> Compiler) js 패턴을 추가하여 수정하였습니다
유용한 정보 감사합니다