読者です 読者をやめる 読者になる 読者になる

日々常々

ふつうのプログラマがあたりまえにしたいこと。

#jjug_ccc 2016 FallでJUnit5の話をしてきた

slide イベント JUnit Java

今年の目標を「1ヶ月に1エントリ以上のペースでブログを書く」にします。 これで9エントリになるので後3ですね。2012年12月は1ヶ月で34エントリ書いてるので、今の私と彼が同一人物なら余裕なはず。

さて、2016-12-03のJJUG CCC 2016 Fallで話させてもらいました。 タイトルはどうしようJUnit 5です。

JJUG CCCについて

参加は6回目だと思ってたけど、7回目だった。どんどんパワフルになっている良いイベント。いい機会をいただけています。ありがとうございます。

資料

準備段階における言い訳をしてみる

1週間前からここ数年無い程度の体調不良に襲われ、滅多に仕事を休んだりしないのですが、2日間お休みしてしまったりしていました。当日は発表前に咳止めを飲んでたり。 あと、11/30にJUnit5.0.0-M3がリリースされて、いろいろと修正が必要になってたりもしてます。junit-jupiter-migration-supportとかM2にはなかったし。まあ準備できてないのはそれだけが理由じゃ無いんだけど。

そんなわけで、お聞き苦しいところもあったかと思いますが、恥じる内容では無いつもりです。

登壇のふりかえり

時間は過不足なく残り30秒程度で終えたはず。時間配分はなんとかなった。 エモ系セッションが多い私ですが、今回はテク系でやろうと思ってやりました。

感想。技術セッションは難しいなーと改めて思いました。

登壇前は「機能の単純な説明はしない。ユーザーガイドを読んでもらった方がいい。」と思ってたのですが、聞いて頂いている方々の反応を見て、機能説明の比重を増やして話しました。合ってたかどうかは知らない。

しかし長丁場のイベントで、単に知識を入れるようなセッションは負荷も大きいんだろうなと。 時間帯や私の話し方(飲み物忘れたのと風邪とで声が出づらかった・・・・・)もあったと思いますが、前回よりお疲れな方が多いように感じました。人数が多かったのもあって、室温も少し高かったのかな。

あと、デモは入れた方がよかったです。目先も変わるし。

今回は時間配分的に入れられなかったけど。

結局JUnit5はどうなんよ?

発表駆動で触っただけですが、私は気に入りました。聞いた方がどうとらえたかは知りません。 リリースされたら即使うと思います。楽しみです。

蛇足: JUnit5開発にあたっては寄付金が募集されたことがあって、キャンペーンページに名前載せてもらってたりする。

宣伝

スライドの中で触れてるAssertJの記事はWEB+DB PRESS Vol.95で書いてます!!

WEB+DB PRESS Vol.95

WEB+DB PRESS Vol.95

JaCoCoとMavenと何か

Java Maven

JaCoCoMavenカバレッジを取ろうってやつ。

  • Java: 1.8.0_102
  • Maven: 3.3.9
  • JaCoCo: 0.7.6.201602180812

いろいろ地味に古いけど気にしない。

普通の手順

設定

丁寧な解説ありますけど、もっと雑なの。

pom.xmlproject/build/pluginsに入れるだけ。

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.7.6.201602180812</version>
</plugin>

別に入れなくてもいいけど、このくらいは書いた方が楽。

実行

mvn clean jacoco:prepare-agent test

面倒ならexecutionに書く。手順は公式の丁寧な解説を参照。

結果を見る

HTMLで手元で見たいなら jacoco:report を実行する。 そしたら target/site/jacoco/index.xml ができる。

Jenkinsにはjacoco.exeを直接見てもらえば、jacoco:reportは不要。

うまくいかない

testフェーズを実行してもjacoco.exeができなくて、jacoco:reportしてたらこんなのが出てたりするとき。

[INFO] --- jacoco-maven-plugin:0.7.6.201602180812:report (default-report) @ xxxxxxxxxxxxxx ---
[INFO] Skipping JaCoCo execution due to missing execution data file:/xxxxxxxxxxxxxx/target/jacoco.exec

たぶんmaven-surefire-pluginになんか設定入ってる。

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.19.1</version>
  <configuration>
    <argLine>-Xms128m</argLine>
  </configuration>
</plugin>

こっちで書いてると、jacoco:prepare-agentで設定したargLineが上書きされてしまう。 なので@{argLine}で参照しておく。

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.19.1</version>
  <configuration>
    <argLine>@{argLine} -Xms128m</argLine>
  </configuration>
</plugin>

だいたいはjacoco:prepare-agentのドキュメントとかに書いてたりするのだけれどね。

「Javaの新定石」でJava EEについて書きました(WEB+DB PRESS vol.94)

Java

WEB+DB PRESS Vol.94

WEB+DB PRESS Vol.94

テーマは最近何かと話題の多いJava EEです。 かんたんなWebアプリをかんたんに作って、そこで使った技術要素を8ページで紹介する試み。 ギリギリまでSpring BootにするかJava EEにするか迷いました。

メインはJAX-RSCDIJPAです。当然ほかの仕様*1も使っていますが、UberJarで使っているPayara Micro以外はJava EE仕様の範囲でやっています。 アプリ自体はシンプルなものなので、ハンズオン的にできなくはないものだとも思っています。 コードのダウンロードもできますので、そちらもどうぞ。

Java EEと言えば、パーフェクト Java EEも出たところですね。 連載で「Java EEもいけるんじゃない?」と思ったら、手を出してみてもいいのではないでしょうか。(わたしもこれからよみます。)

パーフェクト Java EE

パーフェクト Java EE

*1:たとえばJSPServletJTAなど

WEB+DB PRESS vol.93のJavaの新定石は"マルチスレッド/GCとの付き合い方"です。

2016-06-24に発売してました。1ヶ月経ってるので、だいたい読んでくれてると信じてます。まだの方は是非。

WEB+DB PRESS Vol.93

WEB+DB PRESS Vol.93

前回も書いた通り、この連載は「昔からJava使ってるけど、最近の変化とかいちいち追うのめんどい」って方が対象です。今回のマルチスレッド関連はThreadから通して駆け抜けてみたり。書きながら書いたコードは私のGitHubの砂場に転がってたりします。

マルチスレッドとGCについては、Javaエンジニア養成読本の第5章ですこし触れてます。あちらは40ページ中の合わせて1ページでしたが、今回は8ページ中の8ページ。だからどうした。

Javaエンジニア養成読本からは1年半経ってますが、この程度の期間でそれほどJavaのこの辺は変わってませんし、多少増えた私の知識もたいして影響ない程度です。と言うことで、ある意味では書いてる内容やオチに差はないです。見比べたらわかるかも。

Javaエンジニア養成読本 [現場で役立つ最新知識、満載!] (Software Design plus)

Javaエンジニア養成読本 [現場で役立つ最新知識、満載!] (Software Design plus)

ちなみに「Javaの新定石」はうらがみさんと一緒に書かせて貰ってます。何気に一番勉強になってるのは私ではなかろうかね、と思ったり。

WEB+DB PRESS vol.92から「Javaの新定石」って連載、はじめました。

連載はじまります。よろしくおねがいします。

WEB+DB PRESS Vol.92

イメージは高速道路。知識の高速道路とか言うアレです。 ワープや発生ではないです。いきなり新しいものが出てくるのではなく、昔から繋げつつ駆け抜ける感じ……になるのかな。 そんな風なことを書いていきたいなーと思ってます。

メインターゲットは「昔からJava使ってるけど、最近の変化とかいちいち追うのめんどい」って方です。 それだけじゃなく、Javaやってる人に広く合うんじゃないかなー。

定石

あまり関係ないですけど、定石*1って知ってても勝てないんです。 定石を知ってる同士で組み合って、そこからお互い思考を重ねたりして、最後には唯一無二の棋譜ができる。そんな感じ。

定石には理由があるけれど、理由は知らずに手順を暗記しているだけでもそれなりに様になります。 とういうのも、定石は最善手から成立していて、定石の範囲内では基本的に互角になります。

つまり、定石から外れるとは、あえて不利な手を指すことになります。 この際、定石を守ってる側が定石の理由を知らなかったら、一気に崩れることもままあります。 理解していたら、相手の悪手に乗っかって有利に進められることが多いのですけど。

とか何とか言いつつ、もう何年も将棋指してないや。

あ、連載タイトルとはたぶん関係ありません。

*1:私は将棋指しだったので定跡と書く方が多いのだけど

Kotlinに手を出してみる

Kotlinをはじめてみよう。

と思って、こんなことをした。

  • インストールする
  • はろわをかく
  • javapして眺める
  • Kotlinに依存しない形(javaコマンド)でkotlincでコンパイルしたクラスを動かす

GitHubのほうに同じのをあげてるます。

インストールしてみる

sdkmanでいけるんじゃないかと思って、sdk install kotlinを叩いてみる。

% sdk install kotlin

Downloading: kotlin 1.0.1

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   601    0   601    0     0    359      0 --:--:--  0:00:01 --:--:--   558
100 19.6M  100 19.6M    0     0   984k      0  0:00:20  0:00:20 --:--:-- 1586k

Installing: kotlin 1.0.1
Done installing!

Do you want kotlin 1.0.1 to be set as default? (Y/n): y

Setting kotlin 1.0.1 as default.

入ったわ。

げってぃんぐすたーてっどを探す

文法もわからんからとりあえずググる

一番上に公式が出てきてくれた時の安心感。

開いたら当然のように「IDEAでやろうぜ!」って言われる。 まあわかるけど、私はとりあえずコマンドラインvimでやりたいんだーと思ったら、それっぽいのがある。

……ん。sdkmanで入れろって書いてる。 いいや。とりあえずはろーわーるど書いてみよう。

はろわ!

書くぜー。

ふむ。 そしてこんぱいr……ん?

$ kotlinc hello.kt -include-runtime -d hello.jar

なんかコマンド長いなーと思った。 まあいいか。実行したらhello.jar ができた。

サイズは80kbくらい、そこそこでかい。 -include-runtimeとかついてるし、実行可能jarなんだろと思って実行。

% java -jar hello.jar
Hello, World!

できたできた。

zip展開してjavap

どうせ hello.class とかあるんだろうと思ってunzipしたら、なんか HelloKt.class ってのが入ってた。

% javap HelloKt
Compiled from "hello.kt"
public final class HelloKt {
    public static final void main(java.lang.String[]);
}

こいつそのまま実行したらいけるんだろうなーと。

% java HelloKt
Hello, World!

いけた。 んー、これだけならクラスだけでも動くのかな。 って思って、クラスだけ移動して実行。

% java HelloKt
Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
  at HelloKt.main(hello.kt)
  Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

だめか(当たり前だ

mainメソッドの中でクラスロードが入ってる。 なんだろう。

$ javap -v HelloKt
...略
  #15 = Methodref          #11.#14        // kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
...略
public static final void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=2, locals=3, args_size=1
         0: aload_0
         1: ldc           #9                  // String args
         3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
         6: ldc           #17                 // String Hello, World!
         8: astore_1
         9: nop
        10: getstatic     #23                 // Field java/lang/System.out:Ljava/io/PrintStream;
        13: aload_1
        14: invokevirtual #29                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
        17: return
...略

パラメーターのnullチェックをメソッドの先頭でやってるんだなーと。

javap見た感じ、そいつあったら動く気がする。 適当に作ってみる。

そして実行。

% java HelloKt
[Ljava.lang.String;@7852e922
args
Hello, World!

動いた。謎の自己満足。

そんなわけで

Kotlin勉強会の裏で書いてました。

この後は素直にIDEAで触ることにします。

EC2のAmazonLinuxにPayaraを放流してみた

Java AWS

前置き

EC2さん。便利ですよね。使ってますか?私はあまり使ってないです。別にほかのサービス使ってるとかでもないです。(ドヤ顔で目線を逸らしながら

たまに思い出したように触っては、ある程度使えるつもりになって。 しばらくしたら使い方を綺麗さっぱり忘れて、AWS Consoleにログインするたびにいろいろ変わってて戸惑うってのを繰り返しています。 いい加減にしたい。いや、これがいい加減なのか。

ふとしたことから雑なJavaEEアプリケーションを突っ込んだPayara microをEC2で動かしたいなーと思って、また思い出したようにEC2を触るわけで、また一からあれこれやってました。

理想と現実

理想

  • EC2インスタンスを立ち上げて
  • Payaraダウンロードしてきて
  • war放り込んで
  • 起動したら完了

現実

  • EC2立ち上げるかー。microでいいか……ん、そいやnanoとかあったね。知ってる知ってる。聞いた事はある。
  • jdkのインストールとか要ったね。あったあった。
  • payaraさんダウンロード、短縮URLだけど……まあいけるか。
  • コマンドわからん。wgetわからん。yumもわからん。 ← いつものこと
  • さあ起動だ!……ん?……例外? ← new

Payaraさんを放り込んだら例外吐いて死んだ

jdkのインストール

まずはいつものアレ。

$ sudo yum install java-1.8.0-openjdk-devel
$ sudo alternatives --config java
(なんか出てくるので1.8.0を選択)

1.8.0_65だった。まあいいか。

参考: Amazon LinuxでJava8/Tomcat8の環境を構築する

payaraのインストール

次に http://www.payara.fish/downloads からリンクをコピーしてきてwgetする。

$ wget http://bit.ly/1W9d2Lb

ファイル名が 1W9d2Lb になるけど気にしない。 適当にmvした。

payaraの起動

まだwarとか放り込んでないのでそのまま起動する。

$ java -jar payara-micro-4.1.1.154.jar

……ふつうはこれでいいのだけれど、こんなエラーになっちゃって。

$ java -jar payara-micro-4.1.1.154.jar
1 24, 2016 10:33:44 午前 com.sun.enterprise.v3.server.SystemTasksImpl setSystemPropertiesFromEnv
重大: Cannot determine host name, will use localhost exclusively
java.net.UnknownHostException: ip-XXX-XXX-XXX-XXX: ip-XXX-XXX-XXX-XXX: unknown error
    at java.net.InetAddress.getLocalHost(InetAddress.java:1505)
(中略)
    at fish.payara.micro.PayaraMicro.main(PayaraMicro.java:105)
  Caused by: java.net.UnknownHostException: ip-XXX-XXX-XXX-XXX: unknown error
    at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
(中略)
    at java.net.InetAddress.getLocalHost(InetAddress.java:1500)
    ... 29 more

(中略)

[2016-01-24T10:33:55.956+0000] [Payara 4.1] [INFO] [NCLS-JMX-00006] [javax.enterprise.system.jmx] [tid: _ThreadID=87 _ThreadName=Thread-12] [timeMillis: 1453631635956] [levelValue: 800] JMXStartupService has disabled JMXConnector system

Exception in thread "main" java.lang.NullPointerException
  at fish.payara.micro.services.PayaraMicroInstance.setInstanceName(PayaraMicroInstance.java:95)
    at fish.payara.micro.PayaraMicroRuntime.<init>(PayaraMicroRuntime.java:64)
    at fish.payara.micro.PayaraMicro.bootStrap(PayaraMicro.java:710)
    at fish.payara.micro.PayaraMicro.main(PayaraMicro.java:105)

とても悲しい。 起動はしてるのでサーバーのエラーページを表示することはできるのだけれど、--deployでwarを放り込んでも動いてくれない状態だった。

ホスト名が見つからないって言ってて、出てるのはローカルのホスト名。なので /etc/hostslocalhostに足してあげる。

$ hostname
ip-XXX-XXX-XXX-XXX
$ sudo vi /etc/hosts
127.0.0.1   localhost localhost.localdomain ip-XXX-XXX-XXX-XXX

参考: EC2 インスタンス上に Cassandra クラスタを構成する〜 java.net.MalformedURLException の対処 〜

よくわからんけど 動くようになったからよし。

放流

  • scpとかでwarを放り込んで
  • java -jar payara-micro-4.1.1.154.jar --deploy hoge.war で起動

これで完了。やったね。