DropwizardはRESTなフルスタックフレームワークです。
しかし、一部の機能を利用するだけで、ユーザに配布するようなツール作成時にとても役に立ちます。
ここで気軽と思う条件は
- プロジェクトの作成が楽
- buildが楽
- javaだけでなくgroovyでも開発できる
- fat jarで配布・実行が楽
- 利用者が設定ファイルで値を変更できる(例えばユーザ毎の設定とか)
です。
この中で主にDropwizardに関連するのは最後の条件だけですが、これが非常に便利でした。
設定ファイルの入力バリデーターやオブジェクト変換などをDropwizardが担ってくれます。
さらにソースがすっきりします。
他の1〜4の条件は、Gradle、mavenのどちらでも可能です。この記事ではGradleを使います。
1の条件をgradleでやるのは気軽という意味で重要なので、別途記事にすると思います。(気が向いたらですが。。)
簡単に書くと
Mavenのarchetype catalogでプロジェクトを生成し、それで作ったpom.xmlをgradle init
で変換するのが気楽かなと思います。
(gradle-templatesやgradle initだけでもある程度できるけど、まだmaven archetypeに追いついていない気がする。たぶん時間が解決するはずです。)
dropwizard-configuration
まずはGradleを使って2〜4の条件を解決します。
mainClassNameには自分のメインクラスを記述します。
gradle shadowJar
コマンドで実行可能なfat-jarを作成してくれます。
import javax.security.auth.login.Configuration;
import javax.security.auth.login.ConfigurationSpi;
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'groovy'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
mainClassName='com.github.ko2ic.Main'
sourceCompatibility = 1.7
version = '1.0'
repositories { mavenCentral() }
buildscript {
repositories { jcenter() }
dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:1.0.3' }
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.0-beta-1'
compile 'io.dropwizard:dropwizard-configuration:0.7.1'
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
uploadArchives {
repositories {
flatDir { dirs 'repos' }
}
}
jar {
manifest {
attributes('Implementation-Title': 'spike-groovy-executable-jar', 'Implementation-Version': version)
}
}
shadowJar {
tasks.clean.execute()
appendManifest { attributes 'Main-Class': mainClassName }
exclude 'META-INF/*.SF'
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
mergeServiceFiles()
}
startScripts {
applicationName = 'startSpike'
defaultJvmOpts = ['-Xms256m', '-Xmx1024m']
}
注目すべきは、dependenciesのdropwizard-configurationです。
Dropwizardの設計が優れている点の一つに、機能ごとにjarが独立している点です。
ちゃんと意味のある単位でプロジェクトを依存性を考えて作成しています。
なので、dropwizard-configurationだけを切り出して、webではない別のツールでも利用できるのです。
設定ファイルを使うための実装
二つのクラスを作成するだけです。
今回はgroovyで書いていますが、javaでもほとんど同じです。
DropwizardのConfiguration機能を使うための実装です。
たったこれだけで設定ファイル関連のエラー処理、オブジェクト変換がされます。
package com.github.ko2ic.configuration;
import io.dropwizard.configuration.DefaultConfigurationFactoryFactory
import io.dropwizard.configuration.FileConfigurationSourceProvider
import io.dropwizard.jackson.Jackson
import javax.validation.Validation
class ConfigFactory {
static Config create(filePath) {
def objectMapper = Jackson.newObjectMapper();
def defaultFactory = new DefaultConfigurationFactoryFactory();
def validator = Validation.buildDefaultValidatorFactory().getValidator();
def provider = new FileConfigurationSourceProvider();
def configFactory = defaultFactory.create(Config.class, validator, objectMapper, "");
if (filePath) {
return configFactory.build(provider, filePath);
}
return configFactory.build();
}
}
以下は、作成するツールの設定ファイルのオブジェクト表現です。
アノテーションで設定ファイルのバリデーションができます。
このクラスは当然ツールごとに違います。
package com.github.ko2ic.configuration;
import javax.validation.Valid
import javax.validation.constraints.NotNull
import com.fasterxml.jackson.annotation.JsonProperty
class Config {
@JsonProperty("names")
@Valid
@NotNull
def names = [] as HashSet
}
ちなみにこのツールの設定ファイルは以下です。
names:
- test1
- test2
- test3
使い方
コマンド引数に上記設定ファイルのパスを渡します。
例えば、以下のような感じです。
$ java -jar spike-groovy-executable-jar-1.0-all.jar ../../conf.yml
ユーザには、シェルやbatファイルを一緒に付けるといいでしょう。
(gradle startShadowScripts
がうまく動かないため、gradle distShadowZip
コマンドで作成したscriptファイルを変更すると楽です。)
メインクラスでは、設定ファイルのパスを先ほど作ったConfigFactory#create()
に渡して、結果がオブジェクトとして渡されるので、それを利用してツールを実装していくことになります。
package com.github.ko2ic
import com.github.ko2ic.configuration.ConfigFactory
class Main{
static void main(String[] args){
assert args.length > 0 ,'Please specify configuration file.'
def config = ConfigFactory.create(args[0])
config.names.each {
println it
}
}
}
参考
このソースは、以下に置きました。
https://github.com/ko2ic/spike-groovy-executable-jar