Help us understand the problem. What is going on with this article?

最小構成の enkan を Gradle で動かす

More than 3 years have passed since last update.

概要

川島さん(@kawasima)が開発した Java9 時代のマイクロ Web Framework の enkan を Gradle で動かしてみました。enkan の詳細は下記の記事をご覧ください。

  1. enkanとkotowari 〜 Java9時代の新しいマイクロフレームワーク
  2. マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発……JJUG CCC 2016 Spring のセッション

なぜ Gradle?

公式のサンプルだと Maven3 を使うことが推奨されていますし、 JJUG CCC の川島さんのセッションでも Maven3 を使うようにとのお話がありました。が、私の PC には Maven が入っていないので、 Gradle で動かせないかと頑張ってみた次第です。

作業

作業環境

OS Windows 10
Java 1.8.0_91
Gradle 2.12

build.gradle を記述

application plugin を指定

gradle run で起動するために必要です。

plugin
apply plugin: 'application'

mainClassName = 'Main'

Maven repository の指定

oss.sonatype.org を追加します。

plugin
repositories {
    maven {
        url "http://oss.sonatype.org/content/repositories/snapshots"
    }
}

dependencies

動かすには下記の依存が必要でした。

dependencies
dependencies {
    compile 'net.unit8.enkan:kotowari:0.1.0-beta1'
    compile 'net.unit8.enkan:enkan-devel:0.1.0-beta2'
    compile 'net.unit8.enkan:enkan-repl-pseudo:0.1.0-beta1'
    compile 'net.unit8.enkan:enkan-component-undertow:0.1.0-beta1'
    compile 'net.unit8.enkan:enkan-component-metrics:0.1.0-beta1'
    testCompile 'junit:junit:4.12'
}

Java クラスの実装

以下4種類のクラスが必要でした。kotowari-exampleを参考に実装しています。

  1. Main
  2. SystemFactory
  3. ApplicationFactory
  4. Controller

実行

jar作成
$ gradle clean jar
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:jar

BUILD SUCCESSFUL

Total time: 7.629 secs
実行
$ java -jar enkan_verification.jar
java -jar enkan_verification.jar
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
5 23, 2016 9:45:14 午後 org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 5.2.2.Final
enkan> Connected to server (port = 61613)
起動
/start
5 23, 2016 9:45:21 午後 org.xnio.Xnio <clinit>
INFO: XNIO version 3.3.6.Final
5 23, 2016 9:45:21 午後 org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.3.6.Final
Started server

ブラウザから http://localhost:3000/ にアクセスすると 「Hello」 と表示されます。

これでめでたしめでたし……というわけにはいかないようです。

問題

jar にする今回の方法だと、せっかくの Hot reloading の機能を使えません。

run の standardInput を修正

Gradle の run コマンドで標準入力を受け付けられるようにしてみます。

run
run {
    standardInput  = System.in
}

しかし、enkan では標準入力ではなく JLine を使っているようでして、この方法で $ gradle run しても enkan の REPL 操作ができません。standardInput で JLine を指定すればよいのでしょうが、そのやり方がわかりませんでした。これは私の勘違いでした。Mac OS であれば $ gradle run で REPLの起動ができることを確認しています。ただ、Windows ではやはり動いておりません。

Building75%で固まってしまう
enkan_verification>gradle run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
5 28, 2016 10:49:01 午前 org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 5.2.2.Final
enkan> Connected to server (port = 61621)
> Building 75% > :run/start

cmd.png

コマンドプロンプトだけでなく ConEmu や Git Bash でも同様だったので、Windows と gradle run コマンドとの相性なのかと思っています。

追記

Linux + urxvt の環境で動作したと @kawasima さんからコメントをいただきました。Windows の環境固有の問題かもしれません。

追記2

私の方でも Linux サーバ上で何の問題もなく今回のサンプルコードが動作することを確認しております。Linux であれば Gradle でも(compile 以外は)開発可能です。

Mac OS では Main.java のシャットダウンフック設定の場所を入れ替える必要がありました。

修正
final ReplClient replClient = new ReplClient();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {replClient.close();}));
replClient.start(repl.getPort().get());
// Runtime.getRuntime().addShutdownHook(new Thread(() -> {replClient.close();})); //ここじゃダメ

Hot reloading

enkan には変更を自動で反映できる機能があるのですが、この機能は Maven を利用して再コンパイルを実行しているようでして、 Gradle だけの環境ですと下記の例外が発生します。この点に関しましては、要件に Maven3 と書いてありますので当然のことだと思います。enkan の機能をフルに使って開発したいのであれば、推奨環境を用意しましょう。

enkan> /compile
java.lang.IllegalStateException: MAVEN_HOME not set
    at enkan.system.devel.MavenCompiler.execute(MavenCompiler.java:22)
    at enkan.system.devel.DevelCommandRegister.lambda$register$5(DevelCommandRegister.java:68)
    at enkan.system.repl.PseudoRepl.lambda$run$8(PseudoRepl.java:151)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

追記

Gradle でのコンパイルができる devel プロジェクト@kawasima さんが開発してくださいました。現在、develop ブランチで公開されています。

enkan-devel-gradle

依存関係を更新し、 Main.java を下記の通り書き換えれば使えます。

Main.java(for_Gradle)
import enkan.system.command.MetricsCommandRegister;
import enkan.system.devel.DevelCommandRegister;
import enkan.system.devel.compiler.GradleCompiler;
import enkan.system.repl.PseudoRepl;
import enkan.system.repl.ReplBoot;
import enkan.system.repl.pseudo.ReplClient;
import kotowari.system.KotowariCommandRegister;

public class Main {
    public static void main(final String[] args) throws Exception {
        final PseudoRepl repl = new PseudoRepl(SystemFactory.class.getName());
        ReplBoot.start(
                repl,
                new KotowariCommandRegister(),
                new DevelCommandRegister(new GradleCompiler()),
                new MetricsCommandRegister()
                );

        final ReplClient replClient = new ReplClient();
        replClient.start(repl.getPort().get());
    }
}

まとめ

残念ながら Windows + Gradle では enkan の REPL を動かせませんでした。大人しく Maven で動かせばいいのでしょうが、もうしばらく Gradle で動かせないかを調べてみようと思います。何かご存知のことがございましたら、コメント等でお教えくださいますと幸いです。


参考

  1. 今回のソースコード全体
  2. How can I execute a Java application that asks for user input?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした