また TOEIC だ

また今年も TOEIC をやることになった。

会社のお金で TOEIC を年1回くらい受けさせてもらったり、
自腹で何度か受けにいったこともある。

リスニングの点数がなかなか上がらない。
というか、リスニングはほぼ上がっていなくて、
リーディングだけがぐんぐん上がっていく。

けれど、リーディングだけでは限界で、
一定レベル以上のスコアはだせない(ビジネスパーソン平均よりもちょっといい程度)。

リスニングはたぶん壁にぶちあたっていて、
壁を乗り越えないといけない時期なんだろうなという感じ。

とはいえ、英語を勉強することだけに集中することもできずに
いつまでたっても壁の前をウロウロしている。

永遠の優先順位 第3位

・・・と、自分が英語に取り組む姿勢を捉えている。

優先順位の第1位、第2位はマイブームだったりで、コロコロ変わる。
当然そのあたりにある業務、作業、そして趣味には時間を費やす。
一方で、ある時期は第1位だったものが、いきなり圏外に転落するという側面もある。

でも、英語だけは第3位という中途半端な位置をキープし続け、
いつもかすかに意識させられる存在。手を動かすことはないのに。

どうしたらいいんだろうね、今年は。

Gradle の社内勉強会をしてきた

・・・と言うものの、実際に勉強会をしたのは
半年前の 2015年11月 なんですが。

せっかく説明資料もサンプルコードもたくさん作ったので
どこかにアップでもしようかと思いながら、ようやくアップした次第です。

https://speakerdeck.com/hideoku/ming-ri-karashi-itakunaru-gradle

サンプルコードは GitHub にアップしてます。
https://github.com/hideoku/GradleLabo

勉強会をやった経緯

うちの部署では、ハンズオン形式で技術勉強会をやってました。
ひとり1回は講師をしないといけないということで、私は Gradle の入門を。

Gradle 大好きなので、みんなにもとにかく使ってもらおうかなと。

Gradle を使ってみようと思ってもらうことが重要なので
ちょっと偏ってますが「Gradle = 便利ツール」というスキームでやりました。

ビルドツールとして紹介すると、弊社の実情的にまだまだ先進的で、
自分には関係ないやと思われると終わり。それはダメだなと。

準備をとにかくがんばった

どうせ勉強会で紹介したって、後に続かない。
自分で手を動かしてなにか挑戦してみるところまで、なかなかつながらない。

そういうあきらめというか、限界は感じてました。

どうしたら手を動かしてもらえるのかを考えたときに・・・

  • 勉強会の資料だけで、ひとり歩きするくらいのボリュームにしよう
  • はじめの一歩でつまづくときに手助けになるサンプルをたくさん作ろう

この2点を抑えておけば、後から挑戦してみようと思いたったときや
必要にかられて Gradle を勉強せざるを得なくなったときに
説明資料やサンプルコードが助けになるはずだと考えて、準備がんばりました。

勉強会の反響

10数人くらい参加してくれました。
目の前には2人しかいなくて、残りはリモート参加という異様な形でしたが。

「やってみたくなった」というコメントが多かったので、
やってよかったなと素直に思いました。

準備に結構な時間をついやしたので、報われました。

とはいえ、半年たった今、Gradle が浸透しているかというと
そんなことはなさそうです。 必要にかられないと、なかなか実際に使おうとは思わないのが実情です。

おわりに

はじめて Speaker Deck にアップしてみた。

組み込み技術者になりました

ひさかたぶりのブログです。
この2ヶ月で、大きく環境が変化したのでそのことについて書き連ねてみます。

この4月に部署異動となり、Web アプリ開発者から組み込み技術者になりました。

バタバタしている間に本日、6月に突入し、もう2ヶ月か…なんかやばい。
…と思い、ブログを書いてみんとす。

車載ソフトウェア開発

いわゆる、「車載ソフトウェア開発」をすることになりました。
カーエレクトロニクスという分野ですね。

組み込みも分からない、クルマも分からない、C言語も知らない。
そういう最悪の状況です。

Webアプリ から 組み込み へ

10数年ほど、ずっと Java で Web アプリ開発をしてきたわけです。
それがいきなりの畑違いの組み込みに異動です。
ソフトウェア開発といえば同じですが、やっていることは全く異なります。

業務知識、ITスキルともに素人レベルまで落ち込みました。

ハードウェアやネットワーク、そういった物理に近いところでの会話が圧倒的に多くなりました。

Web アプリやら、Java やらやっていると、そういうのは全く意識しないので
いまさらながらに基本的なところから勉強しなおしています。

組み込み開発ではリソースの制約がきびしく、メモリがたった数百KBだったりします。
(ヒープ圧迫してるから、メモリ割り当て 2GB に変更…なんて、異なる世界)

Write once, run anywhere

リソースの制約もそうですが、ハードウェア(マイコン)ごとにコンパイラが違うというのが驚きでした。 コンパイラだけでなく、ソースコードもハードウェア構成によって調整が必要です。

ハードウェアを意識して、プログラミングする必要があります。
リソースも当然気にしないといけない。
これは大変だと。

Java では「Write once, run anywhere」というキーフレーズを目にしてたのですが、
JVM の上で動くから環境非依存でプログラムを使いまわせるよ…と軽く考えていました。

実際にマイコン制御やC言語のことをきちんと学んでみると、run anywhere のスゴさが実感できました。
物理とかハードウェアとかを関心事から除外して、プログラミングできるのはすばらしい。

多くの Java 技術者は「Write once, run anywhere」を理解していないだろうな。

ソフトウェアをインストールするときに gcc や make するのもこの辺が絡んでいるのかなと
素人的に思っています(ちゃんと調べてない)。

自分が組み込みをやる意義

Webアプリでアーキテクチャ構築とかを長年やってきたノウハウを一応持っているつもりです。

Webアプリ開発では当然のことが、組み込み開発ではやっていなかったりします。
たとえば、コンポーネント設計、フレームワーク活用、そういったものが組み込みにはなじみがないようです。
共通化や再利用がまだまだ進んでいないようです。

自分が持っていて、組み込み技術者が持っていないもの。

それがなんであるかを早く把握して、そのギャップを活かすこと。
自分しか持っていない価値を組み込み開発にフィードバックすることが求められているのだと思います。

まだまだ「郷に入っては、郷に従え」で業務知識や組み込み技術をインプットするだけで精一杯。

とはいえ、もう2か月経ったんですよね。
そろそろアウトプットしていかないと…と思い、ブログ書いてみたというわけです。

GradleでExcelを読み込んでなにかを作る

Gradle の社内勉強会をやることになったので、ネタ集めをしています。

「Gradle、実はこういうこともできるよ」ネタを考えてたら
私がよくやるのを紹介したらいいかもと思いつきました。

Gradle はスクリプトベースのビルドツールなので、
極端な話、ガリガリとスクリプトを書けば何でもできます。

ちょっとした Excel 読み込みからの→ファイル生成を個人的によくやります。
自分用の作業テンプレートを作っておく意味もあって、まとめておきたいと思います。

Gradleタスクを作る

build.gradle は以下のような感じです。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.apache.poi:poi:3.13'
        classpath 'org.apache.poi:poi-ooxml:3.13'
    }
}

import org.apache.poi.ss.usermodel.*

task generateMessageIdJava << {

    Workbook workbook = WorkbookFactory.create(
                                  new File("メッセージマスタ.xls"))
    Sheet sheet = workbook.getSheetAt(0)

    new File("MessageId.java").withWriter("UTF-8") { writer ->

        writer << "package sample.constants;\n\n"
        writer << "public class MessageId {\n\n"

        (3 .. sheet.getLastRowNum()).each { rownum ->
            Row row = sheet.getRow(rownum)

            String messageId = row.getCell(0).getStringCellValue()

            // メッセージIDが記載されていない行は書き出さない
            if (messageId?.length() == 0) return

            String message = row.getCell(1).getStringCellValue()

            writer << "    /** $message */\n"
            writer << "    public static final String $messageId"
            writer <<                             " = \"$messageId\";\n"
            writer << "\n"
        }

        writer << "}"
    }
}

やっていること
・buildscript ブロックで Apache POI を使えるように依存関係を設定します。
・同様に、Apache POI が使えるように import 文を追加します。
Excel を1行ずつ読み込みながら、出力ファイルに1行ずつ書き出します。

build.gradle と読み込む Excel ファイルは同じフォルダにある想定です。
出力ファイルも同じフォルダに生成します。

Excel ファイルの中身はこんな感じです。
よくあるマスタ定義ファイルです。

f:id:hideoku:20151111010422p:plain

build.gradle と同じディレクトリに Excel ファイルを配置しておきます。

[とあるフォルダ]
├build.gradle
├メッセージマスタ.xls
└(MessageId.java

タスクを実行してファイルを生成する

gradle generateMessageIdJava

タスクを実行すると、以下のようなファイルが出力されます。
よくみる定数定義ファイルです*1

package sample.constants;

public class MessageId {

    /** 検索しました。検索結果は{0}件です。 */
    public static final String MSG001 = "MSG001";

    /** 登録しました。 */
    public static final String MSG002 = "MSG002";

    /** ユーザIDとパスワードを入力してログインしてください。 */
    public static final String MSG003 = "MSG003";

    /** {0}は入力必須です。 */
    public static final String MSG004 = "MSG004";

    /** {0}は{1}以下の数値で入力してください。 */
    public static final String MSG005 = "MSG005";

}

応用例

このような Gradle タスクを Jenkins などの CI に組み込めば、
設計書が SCM(Subversion, Git etc)にコミットされたのを検知して
自動的に設計書に対応したソースコードを生成して、コミットする
…なんてこともできます。
面倒なルーチンタスクからの解放です。

Gradle Wrapper を使えば、Gradle インストールしていない人にも
使ってもらうことができますね。

*1:こういう定数定義ファイルに意味があるのかどうかは横に置いておきます。そういうものが必要とされる職場があるのだということで。

CheckStyleでテストクラスだけ日本語メソッド名OKにする方法

CheckStyle の設定で苦労したので、作業メモを残しておきます。

やりたいこと

テストクラスはメソッドを日本語で宣言したいので、
テストクラスのメソッドだけを CheckStyle のチェックから外したい。

MethodName モジュールの仕様

メソッドの命名チェックを行っているのは “MethodName" というモジュールです。

<module name="MethodName"/>

CheckStyle の設定ファイルではこんな感じで設定されています。
デフォルト値は省略されていますので、明示的に属性値を書いてみると以下のような感じに。

<module name="MethodName"
               format=“^[a-z][a-zA-Z0-9]*$"
               allowClassName=“false"/>

format 属性で「小文字英字で始まって」「英数字のみ」という命名ルールが規定されています。
記号も日本語もダメ。
allowClassName 属性はクラス名と同じ名前のメソッドを宣言してもよいかどうか(当然 false)。

excludesClassName みたいな属性があれば、「ファイル名が “Test.java” で終わるもの」と
指定できたりしますが、このモジュールは残念ながらそういう属性はありません。

なんとかがんばるしかありません。

SuppressionFilter を使う

SuppressionFilter を使うことで、各モジュールが行うチェックの対象外を指定することができます。
http://checkstyle.sourceforge.net/config_filters.html#SuppressionFilter

便利そうです。

だけれど、ちょっとやっかいです。
いつもの CheckStyle 設定ファイルとは別で、ファイルを作らないといけないです。

いつもの CheckStyle 設定ファイルには
以下のように「SuppressionFilter の設定は別ファイルを見てね」と設定追加します。

<module name="SuppressionFilter">
  <property name="file" value="docs/suppressions.xml"/>
</module>

その参照先となる、別ファイル suppressions.xml を作ります。

<?xml version="1.0"?>

<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">

<suppressions>
  <suppress checks=MethodNamefiles=“.*Test.java$” />
</suppressions>

<suppress> の checks 属性に対象のモジュール名を指定します。
files 属性に正規表現で対象外としたいファイルを指定します。ここではテストクラスの想定。

通常の CheckStyle でファイル指定する感じで “*Test.java” とか指定すると
実行エラーになるので注意です。

suppressions.xml のパス指定がやっかい

いつもの CheckStyle 設定ファイルに suppressions.xml(ファイル名は任意です)のパスを
指定するのですがこれが厄介者です。
いつもの CheckStyle 設定ファイルかの相対パスで見てくれたらいいものの…

CheckStyle を実行する際の作業ディレクトリかどこかからの相対パスっぽいです。
(きちんと調べてませんが、システムプロパティの ”user.dir” とかだと思います)

なので、ひと工夫が必要です。

<ケース1> Eclipse Check Style Plugin の場合

<property name="file" value=“${config_loc}/suppressions.xml"/>

もしくは

<property name="file" value=“${samedir}/suppressions.xml"/>

という感じで変数を使うことで、いつもの設定ファイルがあるディレクトリパスを指定できます*1
Eclipse Check Style Plugin が ${config_loc}, ${samedir} といった組み込み変数を
用意しているみたいです。

${samedir} よりも ${config_loc} を使っている人が多そうなので、
以降は ${config_loc} を使っていきます。

<ケース2> Maven の場合

Eclipse でチェックできるようになったから、次は Maven でチェックだ*2
という流れで、「mvn checkstyle:checkstyle」するとエラーになります。

${config_loc} は Eclipse Plugin の組み込み変数なので、Maven が知らない変数になります。
Maven として config_loc の変数をセットしてあげる必要があります。

pom.xmlCheckStyle plugin がこんな感じで設定されているとして…

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-checkstyle-plugin</artifactId>
   <version>2.8</version>
   <configuration>
     <configLocation>${basedir}/config/checkstyle.xml</configLocation>
   </configuration>
   <executions>
     <execution>
       <phase>verify</phase>
       <goals>
         <goal>check</goal>
       </goals>
     </execution>
   </executions>
 </plugin>

タグにひと工夫を加えます。
タグを追加して config_loc という変数をセットします。

   <configuration>
     <propertyExpansion>config_loc=${basedir}/config</propertyExpansion>
     <configLocation>${config_loc}/checkstyle.xml</configLocation>
   </configuration>

これで Eclipse でも Maven でも、
いつもの設定ファイルからの相対パスで suppressions.xml を指定することできます。

「mvn checkstyle:checkstyle」も動くはずです。

参考にしたサイトなど

色々なサイトの情報をつぎはぎしながら解決しました。

補足

・JavadocMethod(メソッドJavadoc 必須チェック)についても同じような感じで
 対象外指定できます。
Eclipse Plugin で提供される GUI で設定ファイルを編集ようとすると、
 一部の設定情報が欠損したりします。直接ファイル編集したほうが早いです。

        • -

私の Eclipse 環境だと、${config_loc} や ${samedir} で置換されるパスが末尾”/"付きになっていたので、実際は
<property name="file" value=“${config_loc}suppressions.xml”/> という設定です。

いつもは Gradle 使いですが、今はお仕事の都合上 Maven 使ってます。

*1:私の Eclipse 環境だと、${config_loc} や ${samedir} で置換されるパスが末尾”/"付きになっていたので、 実際は <property name="file" value=“${config_loc}suppressions.xml”/> という設定です。

*2:いつもは Gradle 使いですが、今はお仕事の都合上 Maven 使ってます。