Gradleをはじめてみた

Apache Mavenに不満があるかと言うとないのだけど、
Gradleを触ってみることにしました。
それで、Gradleで、Springを使ったRestを試しに作ってみました。
まずは、build.gradleの作成から、
GradleもMavneリポジトリから依存関係を定義したものをダウンロードして来てくれます。
ただし、Mavenとは、依存関係の解釈が違うぽいです。
作ったbuild.gradleは、こんな感じです。

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
sourceCompatibility = 1.8
version = '1.0'
repositories {
    mavenCentral()
}
dependencies {
	// Unit Test Library
	testCompile 'org.mockito:mockito-all:1.9.5'
	testCompile 'org.powermock:powermock-module-junit4:1.5.5'
	testCompile 'org.powermock:powermock-api-mockito:1.5.5'
	testCompile 'com.jayway.jsonpath:json-path:0.9.1'
	testCompile 'junit:junit:4.11'
	testCompile 'org.springframework:spring-test:4.1.2.RELEASE'
	// Web Application Library
	compile 'org.aspectj:aspectjweaver:1.7.3'
	compile 'org.springframework:spring-core:4.1.2.RELEASE'
	compile 'org.springframework:spring-context:4.1.2.RELEASE'
	compile 'org.springframework:spring-context-support:4.1.2.RELEASE'
	compile 'org.springframework:spring-jdbc:4.1.2.RELEASE'
	compile 'org.springframework:spring-tx:4.1.2.RELEASE'
	compile 'org.springframework:spring-web:4.1.2.RELEASE'
	compile 'org.springframework:spring-webmvc:4.1.2.RELEASE'
	compile 'commons-logging:commons-logging:1.1.3'
	compile 'commons-lang:commons-lang:20030203.000129'
	compile 'commons-collections:commons-collections:3.2'
	compile 'org.slf4j:slf4j-api:1.7.5'
	compile 'ch.qos.logback:logback-classic:1.1.2'
	compile 'com.fasterxml.jackson.core:jackson-core:2.4.0'
	compile 'com.fasterxml.jackson.core:jackson-databind:2.4.0'
	compile 'com.fasterxml.jackson.core:jackson-annotations:2.4.0'
	// Web Application Provider Library
	providedCompile 'org.eclipse.jetty:jetty-webapp:9.2.5.v20141112'
}

XMLよりこちらの方が抵抗がなく書けるかもしれません。
Groovyで書けるので、楽かもしれませんが....Groovy自体、そんなに詳しくないので、
これを機にまじめに勉強するかもしれません。
次にRestを作ります。
今回は、単純にメッセージを戻すだけのものにします。
作成したものは、下の3つです。

JSONマッピングクラス
public class HelloMessage implements java.io.Serializable {
	private String id;
	private String message;
	public HelloMessage() {
		super();
	}
	public HelloMessage(String id, String message) {
		super();
		this.id = id;
		this.message = message;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
}
Restサービスインターフェイス
public interface HelloMessageService {
	HelloMessage hello(String messageId) throws Exception;
}
Restサービスインターフェイス実装クラス
@RequestMapping(value="/message")
@RestController
@Service("helloMessageService")
@Scope("request")
public class HelloMessageServiceImpl implements HelloMessageService {
	@RequestMapping(value = "/hello/{messageId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	@Override
	public HelloMessage hello(@PathVariable String messageId) throws Exception {
		return new HelloMessage("hello", "Hello World");
	}
}

とりあえず、Eclipseで見る限り、ビルドは、通ってるようです。
Gradleでもビルドしたら正常にビルド出来ました。

gradle clean build
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:war
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build

BUILD SUCCESSFUL

Total time: 9.581 secs

それで、ここから問題で、Jettyで動かしたいのだが、デフォルトのJetty plugin使ったら
見事に動きませんでした。
なんかJetty関連のライブラリがないとかのエラー。
本家のドキュメントには、パラメーターの設定が少し載っているぐらいで、役にたたない。
これは、時間が掛かりそうなんで、また、今度にすることに...

gradle clean build JettyRun
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:war
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build
:jettyRun
Failed startup of context org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext
java.lang.IllegalArgumentException: Object is not of type class org.eclipse.jetty.webapp.WebAppContext
	at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:189)
	at org.mortbay.jetty.webapp.JettyWebXmlConfiguration.configureWebApp(JettyWebXmlConfiguration.java:103)
	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1269)

次にSpring MVCのテストを書いて、テストが正常に動くかやってみました。
作成したテストクラスは、下のクラスです。

public class TestHelloMessageServiceImpl {
	private static HelloMessageService helloMessageService;
	private MockMvc mockMvc;
	@Before
	public void setUp() throws Exception {
		GenericApplicationContext genericApplicationContext = new GenericApplicationContext();
		XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(genericApplicationContext);
		xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
		ConfigurableListableBeanFactory beanFactory = genericApplicationContext.getBeanFactory();
		Scope request = new SimpleThreadScope();
		beanFactory.registerScope("request", request);
		genericApplicationContext.refresh();
		helloMessageService = (HelloMessageService)genericApplicationContext.getBean("helloMessageService");
		mockMvc = MockMvcBuilders.standaloneSetup(helloMessageService).build();
	}
	@Test
	public void テスト() throws Exception {
		mockMvc.perform(
				get("/message/hello/100")
						.characterEncoding("UTF-8")
						.accept("application/json;charset=UTF-8"))
					.andExpect(status().isOk())
					.andExpect(content().contentType("application/json;charset=UTF-8"))
					.andExpect(jsonPath("$.id").value("hello"))
					.andExpect(jsonPath("$.message").value("Hello World"));
	}
}

それでは、テストを実行!!
これは、すんなりうまく行ったwww。
テストが動作しているか?不明だったので、一度、エラーになるテストを書いて確認したので、
恐らくこれで、大丈夫だと思います。

gradle clean test
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:compileTestJava
:processTestResources
:testClasses
:test

BUILD SUCCESSFUL

Total time: 6.32 secs

とりあえず、今日は、これで終わり。
簡単に触った感じは、楽そうですが、なれるまで、少し時間がかかるかなぁ。
それと、実際で、システムで導入するには、環境依存とか自動生成系のものとか、
テンプレート化など、いろいろあると思うので、
かなり扱えるレベルにならないと使えない気がするので、
お休みの日にひっそりがんばりたいと思います。