IntelliJ IDEA Ultimate Edition と Gradle で Spring Boot を動かして Hot swapping してみるメモ

スポンサーリンク

Spring Boot を試してみました.

環境

IntelliJ IDEA Ultimate Edition 14.0.1
Oracle Java SE 8u25
Gradle 2.2.1
Spring Boot 1.1.9
Ubuntu 14.04.1 64bit

なお,Gradle ではなく Maven を使用した場合はこちら.

IntelliJ IDEA で Spring Boot を動かしてみるメモ
https://hirooka.pro/?p=7524

前準備

Java SE と Gradle をインストールし,IntelliJ を適当な場所に.

tar zxvf ideaIU-14.0.1.tar.gz
sudo mv idea-IU-139.225.3 /usr/local/

プロジェクトの作成

Create New Project で Gradle を選択し,Project SDK を設定します.Use default gradle wrapper (recommanded) を選択します.

作成されたプロジェクトのディレクトリ構造は,下記の通りです.

.
├── build.gradle
├── ExampleSpringBootGradle.iml
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

プロジェクトのトップで右クリックし,New – File – Directory し,下記の 4 つのディレクトリを作成します.

src – main – java
src – main – resources
src – test – java
src – test – resources

java ディレクトリを右クリックし,Mark Directory As しなくても各々 Source Root,Resources Root,Test Source Root,Test Resources Root と自動設定されます.

適当なパッケージを作成し,アプリケーションを実行するために main メソッドを持つ適当なクラスを作成しておきます.

例えばディレクトリ構造は下記の通りです.

.
├── build.gradle
├── ExampleSpringBootGradle.iml
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── pro
    │   │       └── hirooka
    │   │           └── example_spring_boot_gradle
    │   │               └── Application.java
    │   └── resources
    └── test
        ├── java
        └── resources

build.gradle

まず,build.gradle を編集してみます.

https://github.com/spring-guides/gs-spring-boot/blob/master/initial/build.gradle を参考にします.

プロジェクト作成直後の build.gradle は下記の通りです.

apply plugin: 'java'

sourceCompatibility = 1.5
version = '1.0'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

下記のように編集してみます.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.9.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'example-spring-boot-gradle'
    version = '0.1.0'
}

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.2.1'
}

dependency をダウンロードします.

View – Tool Windows – Gradle で,リフレッシュっぽいアイコンをクリックするとダウンロードが始まります.

main メソッドを持つクラス

Spring Boot は,public static void main をエントリーポイントとして組み込みウェブサーバを立ち上げてくれるようです.

src/main/java を右クリックし,[New] –

 を選択し,Name を “Application” とする Class を作成してみます.

Application.java を下記のように編集してみます.

[java]
package pro.hirooka.example_spring_boot_gradle;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args){
        SpringApplication.run(Application.class, args);
    }
}

@RestController
class GreetingController {

    @RequestMapping("/hello/{name}")
    String hello(@PathVariable String name) {
        return "Hello, " + name + "!";
    }
}

プロジェクトの実行

IntelliJ 上でプロジェクトを実行してみます.Spring Boot に組み込まれている Tomcat が起動し,その上でウェブアプリケーションが動く,という形になります.

IntelliJ のメニューの [Run] – [Edit Configurations…] で,プラスボタンをクリックし,[Gradle] を選択します.Gradle が追加されます.

Name を任意のものに設定します.Gradle project で,プロジェクトの build.gradle を指定します.Tasks に bootRun と記述します.[OK] ボタンを押します.

IntelliJ のメニューの [Run] – [Run “Name”] で実行してみます.

下記のようなログが表示され,下記のように Tomcat が動き,ウェブアプリケーションが動くような内容になっていることを確認します.

12:20:15 AM: Executing external task 'bootRun'...
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:findMainClass
:bootRun

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.1.9.RELEASE)

2014-11-30 00:20:20.567  INFO 6088 --- [           main] p.h.e.Application                        : Starting Application on dev with PID 6088 (/home/hirooka/IdeaProjects/ExampleSpringBootGradle/build/classes/main started by hirooka in /home/hirooka/IdeaProjects/ExampleSpringBootGradle)
2014-11-30 00:20:20.595  INFO 6088 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@17695df3: startup date [Sun Nov 30 00:20:20 JST 2014]; root of context hierarchy
2014-11-30 00:20:21.029  INFO 6088 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2014-11-30 00:20:21.485  INFO 6088 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-11-30 00:20:21.638  INFO 6088 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2014-11-30 00:20:21.640  INFO 6088 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.56
2014-11-30 00:20:21.731  INFO 6088 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-11-30 00:20:21.732  INFO 6088 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1140 ms
2014-11-30 00:20:22.168  INFO 6088 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2014-11-30 00:20:22.171  INFO 6088 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2014-11-30 00:20:22.339  INFO 6088 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-11-30 00:20:22.466  INFO 6088 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello/{name}],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto java.lang.String pro.hirooka.example_spring_boot_gradle.GreetingController.hello(java.lang.String)
2014-11-30 00:20:22.469  INFO 6088 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=,custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2014-11-30 00:20:22.470  INFO 6088 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2014-11-30 00:20:22.484  INFO 6088 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-11-30 00:20:22.485  INFO 6088 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-11-30 00:20:22.599  INFO 6088 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2014-11-30 00:20:22.656  INFO 6088 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-11-30 00:20:22.658  INFO 6088 --- [           main] p.h.e.Application                        : Started Application in 2.407 seconds (JVM running for 2.674)

ウェブアプリケーションの動作確認

ウェブブラウザで例えば

http://localhost:8080/hello/hirooka

にアクセスしてみます.

Hello, hirooka! のように表示されれば,ウェブアプリケーションが正常に動作しています.

実行可能な jar ファイルの作成

[Run] – [Edit Configurations…] の Tasks で build と記述して Run します.

1:42:26 AM: Executing external task 'build'...
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar
:bootRepackage
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 3.263 secs
1:42:29 AM: External task execution finished 'build'.

Run すると build ディレクトリに jar ファイルが生成されています.

./build/libs/example-spring-boot-gradle-0.1.0.jar

下記のように実行すると,組み込み Tomcat でウェブアプリケーションが稼働します.

java -jar example-spring-boot-gradle-0.1.0.jar 

Hot swapping

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html#howto-reload-java-classes-without-restarting を参考にします.

build.gradle の buildscript に springloaded を追記します.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.1.9.RELEASE"
        classpath 'org.springframework:springloaded:1.2.0.RELEASE'
    }
}

任意のソースの任意の箇所を修正,保存し,[Build] – [Compile “”] ([Ctrl] + [Shift] + [F9]) します.Console が更新されます.Tomcat を再起動することなく,ソースの変更がウェブアプリケーションに反映されていることを確認します.

参考

Building an Application with Spring Boot
http://spring.io/guides/gs/spring-boot/

17. Running your application – Part III. Using Spring Boot –
http://docs.spring.io/autorepo/docs/spring-boot/1.1.9.RELEASE/reference/html/using-boot-running-your-application.html#using-boot-running-from-an-ide

Spring
スポンサーリンク
コピペワールド