転職しました

(※古巣への不満とか、そういうのは無しです)

f:id:knjname:20140729003759p:plain

転職しました。

みなさま、その節は大変お世話になりました。

これからも変わらずプログラマとして、皆様に笑顔になっていたけるよう精進してまいります。

(一部の方へ)飲み会など良い機会ありましたら、またご一緒させてください。

FindBugs 3.0.0 (Java8対応) リリースされてた

http://findbugs.sourceforge.net/

FindBugs 3.0.0が昨日リリースされていたようです!(Eclipseプラグインもリリースされています)

Java8対応になりました!

はっきりいって https://mailman.cs.umd.edu/pipermail/findbugs-discuss/2014-May/003995.html このMLのスレッド読んだ時はもう年内は絶望的だと思っていましたが、よかったー。

これまでJava7ターゲットでクラスファイルを出そうがJava8でFindBugsを動かす限り落ちていたので、とても助かります。

で、さっそく私も使い始めましたが、ちゃんと動いているようです。(注意される警告がやや増えた気がする)

多くのJava8移行者にとって、EclipseFindBugsCheckstyleがJava8未対応というのがかなりの痛手でしたが、先月末からEclipse Lunaがリリースされ、そしてFindBugsがリリースされ、状況がかなり改善されてきてますね。

あとはCheckstyleを待つのみです。

(しかし、本当に人の善意に頼ってOSSは成り立っているものだと感じました。)

追記:CheckstyleのJava8対応について

https://github.com/checkstyle/checkstyle/issues/10

sabaka commented on 14 May Hi! It is my GSOC issue. It has to be done till 18th of August, but I'm going to finish in July.

Also, after discuss with team, we decide, that implementation of ignoring option for Java 8 features is painful, and may break grammar. Unfortunately community has to wait for full implementation of Java 8 features.

プロジェクトメンバの立ち位置がよくわかんないですが、これを見る限りでは、とりあえず対応ではなく、ちゃんとしたJava8対応を8月半ばまでに投入予定みたいですね。

Dockerを使い始めて半年弱

Dockerを使い始めて半年弱ぐらい経ったような気がする。

Dockerを知ったきっかけは、はてブTwitterのTLに流れていたのを見たのがきっかけだと思う。

(みんな新しい技術どうやって知ってるの?と思う人はそういうところをこまめに見ればよい。気に入ったブログはFeedlyに登録すればいい。)

仕事では開発サーバにDocker on Ubuntu on KVM on Ubuntu on BM(Bare Metal)な状態で、JenkinsやRedmineなどの開発用サービスコンテナとして使ってる。

(Dockerを使ってJenkinsでビルドとか面白いことは残念ながらやってません。:-P )

Docker meetup Tokyo #3でもあったんだけれども、開発用サーバに使う人は1マシン複数コンテナが普通のようだ。

逆に不確定要素を排除したいプロダクションだと1マシン1コンテナだったりもするらしい。

私が、なぜ開発用サーバにDockerを使っているかといえば、私が以前立てていた開発用サーバは、私が便利とあらば、生産性をあげるために、ガンガン新しいサービスやアプリを入れてしまっていた。結果、そいつらの構成が1つのOS上でぐちゃぐちゃになってしまい、何がどう絡んでいるのか把握しづらいというプチ問題に発展した。

だから、とりあえず各開発用サービスがコンテナとして明確に分離されれば、少しはこのカオス状態がまともになると思い、Dockerを使った。Dockerfileがクソみたいになっても、Dockerが1.0に達していなくて不安な夜を過ごしても、このメリットを何度も自分に言い聞かせた。

やはり良い垣根というのはソフトウェアにおいては大事である。

また、一つの開発用サービスを用途ごとに複数立てたいという要求もあり、Dockerを使えばコンテナイメージを環境変数etcをかえて使い回しすればいいので、そういう意味でもDockerは役に立った。

たとえば、普通にJenkinsをYUMやらで入れたとして、これを複数インスタンス立ち上げるのはちょっと苦痛だろう。

そういう場合はDockerを使って、Jenkinsのイメージを使いまわせばいいのである。細かい要件はJenkinsスレーブ(こちらもDockerイメージ)に吸収させれば少なくともJenkinsマスタのイメージは複数インスタンスで使いまわせる。

Dockerfileは多くの開発者が慣れ親しんでいるCentOSベースに、ある程度万能な状態のコンテナを派生させて色々作ったが、今思えばもっとフラットに構成すればよかったと思っている。結局、万能層なんて置くと外から見て何がどうなっているのかわかりづらい。

docker pullして済むようなものについては、特に自分でイメージもつくらずに使っている。ただ、そんなことができるのはレアケースで、大概本格的に使うなら、自分でケツを拭けるコンテナじゃないと行き詰まることが多いはずだ。

既存のLinuxソフトウェアはDockerなんぞ知らんという作りになっているので、うまくイメージに落とせないことも多いし、開発用メールサーバとしてpostfixdovecotをコンテナに閉じ込めるのは私にとっては非常に苦痛だった。

この類の苦痛の回避策として、アプリをうまく事前準備なしで初期化動作をさせようとすると、コンテナに起動用シェルが待ち構えて本丸を最後にforkかexecかするケースが多い気がする。

タイムゾーンとかズレたり、好きなDNS見させるのに苦労したり、ログの吐き場所とか苦労したりなんか色々苦労した。

そもそもDockerを扱っていて、これLinuxの知識割りと要るよねと思うこと多数。今Dockerを自由自在につかえている人はLinuxに相当詳しいはず。

まあこういう雑魚が引っかかる問題はバージョン上がったら古い人しか知らないアホみたいな問題になっているのかもしれないけど。

それとプロキシを噛ませないといけない環境だと死ぬほど苦労した。

コンテナのyumやaptがそのままじゃプロキシ見ないので、じゃあ、どうするかっていう…。Dockerのデーモン自体がプロキシ見るのは簡単なんですけどね。プロキシの設定がコンテナに残るとか気持ち悪すぎる。

そもそもプロキシがなくてもビルド中のインターネットアクセスが割りと苦痛だったりする。キャッシュプロキシは不可避だろうか。

Dockerとは何か?

Docker初心者が口にする最も多い質問だと思う。

Linux専門の)VMの1種というと分かりやすいけど、違う。

(ただ、初心者にとってはSSHDをDockerで立てれば、それがたぶんいっぱしのサーバに見えてくる的な感覚?はあると思う。)

Dockerの哲学をあらわすのはアプリケーションコンテナという言葉だと思う。

たとえばJavaで何かのアプリケーションを作っていたとして、それがどんなJREで動くのか非常に曖昧だったり、どういうディレクトリ構造が実際にあるのか曖昧だったりで、やる気のある人はサーバ環境をChefとかで構成してみるものの、やや実環境の構成の不明瞭さに一抹の不安感が漂ったりすると思う。

そういった場合に、アプリケーションがどこかのディレクトリにインストールされ、どこかの/usr/binにあるバイナリが存在するのを期待するという受け身のアプリという姿勢から、1段階引き上げて、OSの環境ごとアプリを封じ込めて、それをそのままいろんな環境に持っていければ、あまり実環境の構成の不明瞭さを気にしなくてもよくなる。

これがDockerのアプリケーションコンテナという考え方であると思うし、Dockerfileもそれに準拠する形で作れば、そうそう狂ったものにならない、と思っている。

ただ、Dockerはあくまで道具だし、綺麗にならないものもいっぱいあるし、時間は有限だし、私イジけちゃうしってことで、まあただのアプリの檻として好きに使っても後ろ指さされることはないと思います。

Dockerの檻としてのセキュリティはどうなんですかね~。Dockerチームは確かそういうのにケアしているとか言っていたような気が1mmぐらいはしますが、セキュリティ確保は副次的なものだと思ってます。

信用できないコンテナとかは動かせないんじゃないんでしょうか。

Dockerで個人的に消化不良起こしているもの

  • Ambassadorパターン
  • supervisordという存在
  • ロールベース

Dockerで個人的に期待すること

AntでEclipseのECJ(Eclipse Compiler for Java)を使う

はじめに

知っている人にはよく知られていることですが、EclipseJava開発環境、JDTがJavaソースのコンパイルに使っているコンパイラは、OracleJDKなどとは違い、Eclipseが独自実装しているコンパイラ ECJ (Eclipse Compiler for Java)です。

ECJとOracle JDK(OpenJDK)のjavacと何が違うのかというと、

  • コンパイラの許容ルールが異なる。(おそらくOracle JDKより緩いケースが多そう)
    • これのせいでEclipseコンパイルできたとしても、javacでコンパイルできないソースが出るので、そういうのやめたい人はきちんとJenkinsとかで常時チェックかかるようにしましょう。
  • コンパイルが一部失敗しても成功したclassファイルは生成される。
    • それどころか失敗したクラスでさえ仮のclassファイルを生成させることができる。
    • ある程度のコンパイルエラーを許容しなければならない荒っぽいプロジェクトでは使える性質でしょう。
  • コンパイラオプションが異なる。
  • 警告などの出力フォーマットが異なる。
    • JenkinsでWarnings Pluginを使っている場合は、ECJ用のルールがデフォルトで存在しています。

ECJはEclipseを立ちあげなくてもAntから使えます。(batch compiler)

んじゃあ、AntでEclipseJavaソースコンパイラ使ってみよう

プレーンなbuild.xml

たとえば、下記のようなフォルダ構成だったとします。

project-root/
  build.xml
  src/
    Hoge.java
  compiled/
    (Hoge.classがここにできればいいな)

この場合、build.xmlはこうなるでしょう。(わざとシンプルにしてます。Ant1.8以上)

<project default="build">
       <target name="build">
             <delete dir="compiled" />
             <mkdir dir="compiled" />
             <javac srcdir="src" destdir="compiled" />
       </target>
</project>

上記例だとパスの通ってるjavacを叩いているので、これをECJに切り替えましょう。

ECJを手に入れよう

ECJを構成するJARを手に入れましょう。

入手方法1. 直接ダウンロード

下記のMavenリポジトリ

http://mvnrepository.com/artifact/org.eclipse.jdt.core.compiler/ecj/

で見つかりました。 (groupId=org.eclipse.jdt.core.compiler, artifactId=ecj)

どっか公式DLページあるんですかね?(検索あきらめた)

ecj-..jar をダウンロードしましょう。JARの中にAnt用のアダプタとコンパイラコア本体が入っています。

ここでは project-root/ant-lib/ にそのjarをおいておきます。

入手方法2. Eclipseから取得

Eclipse本体からでも取得できます。

まずは下記の場所からJDTのコアのプラグインJARを見つけましょう。

eclipseインストールパス/plugins/
  org.eclipse.jdt.core_3.10.0.v20140604-1726.jar みたいなの

んで、上記jarをzipファイルとして解凍してAntへのアダプタとなる jdtCompilerAdapter.jar をとっておきましょう。

ここでは下記2つのJARを project-root/ant-lib/ にいれておきます。

  • org.eclipse.jdt.core_3.10.0.v20140604-1726.jar
  • jdtCompilerAdapter.jar

Ant関係なくECJを起動してみよう

ECJはスタンドアロンでjavacのように扱うことが可能です。javacと基本ほとんど同じですね。

java -jar ECJJARファイル コンパイルしたいソース.java

※ECJJARファイルはそれぞれ下記を使用。
 入手方法1の場合はecj-*.*.jar
 入手方法2の場合はorg.eclipse.jdt.core_3.10.0.v20140604-1726.jar
※マニフェストで起動したくない場合は起動クラスとして org.eclipse.jdt.internal.compiler.batch.Main を指定すればよい。
※依存するライブラリがある場合は-classpath "依存.jar"みたいな感じでjavaに渡してあげる。
※細かいオプションみたい人は -? 引数を指定してみてね。

ECJをbuild.xmlに組み込んでAntから呼んでみよう

ECJをtypedefし、それをjavacで参照、javacのcompilerでorg.eclipse.jdt.core.JDTCompilerAdapterを使うように指定すればOKです。

<project default="build">
     <typedef name="ecj" classname="org.eclipse.jdt.core.JDTCompilerAdapter">
          <classpath>
               <fileset dir="ant-lib" includes="*.jar" />
          </classpath>
     </typedef>
     <target name="build">
          <delete dir="compiled" />
          <mkdir dir="compiled" />
          <javac srcdir="src" destdir="compiled" compiler="org.eclipse.jdt.core.JDTCompilerAdapter">
               <ecj />
          </javac>
     </target>
</project>

typedef+<ecj />が面倒な人は、下記のいずれかのようにすれば、compiler属性の指定だけで使えます。

  • Ant起動時に-lib ECJのjarを指定する。
  • ${ANT_HOME}/lib~/.ant/lib にそのままECJ関連のjar放り込む。
  • typedefを作らず下記のようにcompilerclasspathをインラインで書く。
          <javac srcdir="src" destdir="compiled">
               <compilerclasspath>
                    <fileset dir="ant-lib" includes="*.jar" />
               </compilerclasspath>
          </javac>

compiler属性の指定が面倒な人は、下記のいずれかをすればいいでしょう。

  • <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />をどこかに入れておいたり、
  • Antの起動引数でプロパティ指定しておけば

まあ、macrodefとか使ってもいいと思うし、お好きに。

動作させてみよう

さっそくこれを動かしてみると、(わざとエラー出させています)

Buildfile: F:\eclipse-luna\workspace\CompileWithEclipseCompiler\build.xml
build :
   [ delete] Deleting directory F:\eclipse-luna\workspace\CompileWithEclipseCompiler\compiled
    [ mkdir ] Created dir: F:\eclipse-luna\workspace\CompileWithEclipseCompiler\compiled
    [ javac ] F:\eclipse-luna\workspace\CompileWithEclipseCompiler\build.xml:6: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [ javac ] Compiling 1 source file to F:\eclipse-luna\workspace\CompileWithEclipseCompiler\compiled
    [ javac ] ----------
    [ javac ] 1. ERROR in F:\eclipse-luna\workspace\CompileWithEclipseCompiler\src\Hoge.java (at  line 5)
    [ javac ]       String missing_semicolon
    [ javac ]              ^^^^^^^^^^^^^^^^^
    [ javac ] Syntax error, insert ";" to complete BlockStatements
    [ javac ] ----------
    [ javac ] 1 problem (1 error)

BUILD FAILED
F:\eclipse-luna\workspace\CompileWithEclipseCompiler\build.xml:6: Compile failed; see the compiler error output for details.

Total time: 752 milliseconds

ちょっと出力ログ形式がOracle JDK(下記)と違いますね。

    [ javac ] F:\eclipse-luna\workspace\CompileWithEclipseCompiler\src\Hoge.java :5: エラー: ';'がありません
    [ javac ]             String missing_semicolon
    [ javac ]                                     ^
    [ javac ] エラー1個

もちろんコンパイルが成功した場合はclassファイルがcompiledフォルダに出力されます。

独自オプション

コンパイラのオプションは http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-using_batch_compiler.htm とかにまとまっています。

たとえば-proceedOnErrorというのを下記のように指定すれば、(compilearg要素@line属性)

          <javac srcdir="src" destdir="compiled" compiler="org.eclipse.jdt.core.JDTCompilerAdapter">
               <ecj />
               <compilerarg line="-proceedOnError" />
          </javac>

エラーがでているクラスでも仮のclassファイルを生成してくれます。

もちろんコンパイルエラーが発生しているメソッドを呼んだりすると Exception in thread "main" java.lang.Error: Unresolved compilation problem: などと怒られます。

まとめ

Eclipseコンパイラを使うことでしか動作できないプロジェクト作るのやめてほしいです…(切実)

試しにDockerリポジトリにイメージ(knjname/jenkins)登録してみた

試しにDockerリポジトリに自作イメージ登録してみました。

無料アカウントだと1つまでプライベートDockerリポジトリを持てるみたいです。

今回はknjname/jenkinsというDockerイメージを公開リポジトリにpushしてみました。

SCM : https://github.com/knjname/docker-jenkins

Dockerレポジトリ : https://registry.hub.docker.com/u/knjname/jenkins/

登録する時はあらかじめリポジトリを作っておいて(今回はknjname/jenkinsとして作成)、下記のようにすれば勝手に作成したリポジトリに収まります。

docker push knjname/jenkins
# この後アカウント情報訊かれる

使い方は簡単。

docker run --name testjenkins -d -p 8080:8080 knjname/jenkins

http://localhost:8080 にアクセスすればJenkinsが立ち上がっているのが見えるはずです。

(2014-06-13 追記)なお、このあとGithubと連携するAutomated Buildを試すためにリポジトリを作りなおしたところ、未だにビルドがされていない模様…。

(2014-06-14 追記)ようやくビルドされました!なんかDockerhub自体はまだまだ不安定なところがあるかもしれませんね。

Docker 1.0が出たし、Windows(x64)でDockerが使えるようになりました

Docker 1.0が出ました。待ってたよ!

http://blog.docker.com/2014/06/its-here-docker-1-0/

そして64bit Windows用の、boot2dockerによるWindows用Dockerも出ました。

https://docs.docker.com/installation/windows/

とは言ってもWindowsLinuxが動くわけがないわけで、単純にVirtualBox上に小さなLinux(Core Linux)を動かし、その上でDocker(boot2dockerというイメージ)を動かしているだけですね。(OS X版も同じ)

別にWindowsファイルシステムをフル利用したUnionなFSが使われてるとかそういう夢のある話はありません。

てなわけで、結局は

  • DockerをWindowsでバリバリ使いたい人は、VirtualBoxでUbuntu14.10 Serverとか立ち上げてマニュアルでDockerインストールして使う
  • Dockerのイメージを動かしたいだけとか、忙しい人はWindows用のDocker(boot2docker)を使う

という具合になりそうです。どちらもVirtualBox上でLinuxが動くというだけの話です。

ちなみに入れてみたところ、感触としてはVagrantっぽい感じですね。