--- title: JRebel でSpring Bootアプリケーションの快適リローディング (IntelliJ IDEA編) tags: ["IntelliJ IDEA", "JRebel", "Spring Boot"] categories: ["Dev", "IDE", "IntelliJIDEA", "JRebel"] date: 2015-05-17T06:54:04Z updated: 2015-05-17T06:54:04Z --- Javaアプリケーション実行中に動的にクラスをリロードをしてくれる[JRebel](https://zeroturnaround.com/software/jrebel/)がとても便利なので紹介します。特にSpring Bootのようなスタンドアローンアプリケーションの開発中にとても有用です。 ここではIntelliJ IDEAでセットアップします。[Eclipse](http://zeroturnaround.com/software/jrebel/quickstart/eclipse/)でも、[NetBeans](http://zeroturnaround.com/software/jrebel/quickstart/netbeans/)でも使えます。 **File > Settings**を開き、**Plugins**を選択します。 **Browse Repositories**をクリックし、**JRebel Plugin**を探し、**Install plugin**ボタンをクリックします。 ![image](https://qiita-image-store.s3.amazonaws.com/0/1852/017aae52-9816-1b79-7405-684457c3e23e.png) IntelliJ IDEAを再起動すると、**Run with JRebel**コマンドが追加されます。 次の簡単なSpring Bootを実行します。 ``` java package demo; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class DemoApplication { @Bean CommandLineRunner foo() { return args -> System.out.println("hoge!"); } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` ![image](https://qiita-image-store.s3.amazonaws.com/0/1852/b8c8d077-de7f-9f57-220d-a9298098e3dd.png) `DemoApplication`クラスを右クリックして、**Run with JRebel "DemoApplication"**を実行しようとすると、初回はアクティベーションを求められます。 ![image](https://qiita-image-store.s3.amazonaws.com/0/1852/44687792-7221-da2a-343f-ff849378234c.png) 14日間のフリートライアルを使うか、ライセンスキーを入力する必要があります。わたしは**非商用の個人利用に限り**使用できる、[myJRebel](https://my.jrebel.com/)のライセンスキーを取得したので、それを入力します。 ![image](https://qiita-image-store.s3.amazonaws.com/0/1852/0c62ed3a-632e-d142-ca9e-fe8a3c30f2b2.png) **Activate JRebel**ボタンを押せば、アクティベーションが完了します。 ![image](https://qiita-image-store.s3.amazonaws.com/0/1852/34749793-44b6-de94-6919-929974c67871.png) 再度、**Run with JRebel "DemoApplication"**を実行すれば、以下のようなJRebelのログが出力されたあと、アプリケーションが起動します。 ``` 2015-05-17 16:00:16 JRebel: Contacting myJRebel server .. 2015-05-17 16:00:18 JRebel: 2015-05-17 16:00:18 JRebel: ############################################################# 2015-05-17 16:00:18 JRebel: 2015-05-17 16:00:18 JRebel: JRebel Legacy Agent 6.1.3 (201504281742) 2015-05-17 16:00:18 JRebel: (c) Copyright ZeroTurnaround AS, Estonia, Tartu. 2015-05-17 16:00:18 JRebel: 2015-05-17 16:00:18 JRebel: Over the last 1 days JRebel prevented 2015-05-17 16:00:18 JRebel: at least 6 redeploys/restarts saving you about 0.2 hours. 2015-05-17 16:00:18 JRebel: 2015-05-17 16:00:18 JRebel: Licensed to Toshiaki Maki (using myJRebel). 2015-05-17 16:00:18 JRebel: 2015-05-17 16:00:18 JRebel: 2015-05-17 16:00:18 JRebel: ############################################################# 2015-05-17 16:00:18 JRebel: 2015-05-17 16:00:19 JRebel: Monitoring resource '/Users/maki/git/firstapp/target/classes/application.properties'. . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.2.3.RELEASE) ... ``` アプリケーションを立ち上げたまま、以下のようにソースコードを修正します。 ``` java package demo; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class DemoApplication { @Bean CommandLineRunner foo() { return args -> System.out.println("hoge!"); } @RequestMapping("/") String hello() { return "hello"; } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 右クリックして、**Compile 'DemoApplication.java'*をクリックし、`http://localhost:8080`にアクセスすると、 ``` 2015-05-17 16:09:37 JRebel: Reloading class 'demo.DemoApplication'. 2015-05-17 16:09:37 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580'. 2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580'. 2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$FastClassBySpringCGLIB$$7211a142'. 2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580$$FastClassBySpringCGLIB$$54aa9091'. 2015-05-17 16:09:38 JRebel: Reinitialized class 'demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580$$FastClassBySpringCGLIB$$54aa9091'. 2015-05-17 16:09:38 JRebel: Reconfiguring bean 'demoApplication' [demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580] 2015-05-17 16:09:38 JRebel: Reconfiguring bean 'demoApplication' [demo.DemoApplication$$EnhancerBySpringCGLIB$$8d24a580] 2015-05-17 16:09:38.927 INFO 1853 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2015-05-17 16:09:38.928 INFO 1853 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2015-05-17 16:09:38.970 INFO 1853 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 41 ms 2015-05-17 16:09:39.000 INFO 1853 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2015-05-17 16:09:39.007 INFO 1853 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto java.lang.String demo.DemoApplication.hello() 2015-05-17 16:09:39.009 INFO 1853 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2015-05-17 16:09:39.009 INFO 1853 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest) ``` というように影響のあるクラスがリロードされていることがわかります。アプリケーション再起動に比べてかなり高速に動作するので、作業効率が大幅に向上すると思われます。 リロード時のGifアニメ貼っておきます。 一々、右クリックコンパイルするのは面倒なので、`Ctrl+S`に**Make Project**をマッピングさせておくと、便利です。 ![image](https://qiita-image-store.s3.amazonaws.com/0/1852/57b1b978-e960-62f6-7279-3b91db0be4ec.png) ![image](https://qiita-image-store.s3.amazonaws.com/0/1852/81967446-9566-5435-21f5-927a308bc307.png) ソースを修正するだけ修正したあと、`Ctrl+S`を実行し、アプリケーションにアクセスすればリロードされます。 再DIもそこそこ対応しており、Spring Loadedみたいに不安定ではないので、かなりオススメです。 気に入ったら商用ライセンスを買いましょう。お買い求めは[Samuraism](http://samuraism.com/products/zeroturnaround/jrebel)まで!