garbagetown

個人の日記です

ドキュメント翻訳の裏側

この記事は Play framework Advent Calendar 2014 - Adventar の四日目です。空いているようなので埋めます。

五日目の立候補者がいないので誰か書いてください。

新規翻訳と差分翻訳

Play Framework のドキュメントは日々更新され続けています。いずれは原文の更新を検知して、すぐさま翻訳する仕組みを作れたらと思いますが、今のところ翻訳プロジェクトでは Play Framework の新しいバージョンがリリースされるたびに、手作業で地道に更新内容を確認しています。

更新内容には大きく分けて、ドキュメントの追加、更新、削除の三種類があり、削除されたドキュメントはもちろん翻訳対象外ですし、追加されたドキュメントは何も考えずに翻訳すればいいのですが、難しいのが更新されたドキュメントです。

原文に変更がない箇所まで再度翻訳するのは無駄なので、翻訳プロジェクトでは以下のように対策しています。

issues のラベルと diff 表示

前回の記事 で、しれっと「ファイル名などで issues を検索します」と書いたとおり、翻訳プロジェクトでは翻訳対象のドキュメントを issues に登録しています。

このとき、更新されたドキュメントの場合は、以下のように update ラベルを付けて、issues の本文に diff の結果を貼り付けています。

f:id:garbagetown:20141205005026p:plain

リリースごとに大体 120 個くらいの issues を登録するので、さすがに手作業では厳しく、issues を登録するツール を作って対応しています。

翻訳対象のドキュメントを issues 化するというアイディアは @masahito さんのもので、当時は Pyhton で書かれていたようです。diff を含める機能を追加したかったのですが、ぼくが Python を書けないので Java で作り直しました。

これにより、このドキュメントが更新されたものであることと、更新された内容がひと目で分かるようになりましたが、差分が多くて面倒くさそうな issues がいつまで経っても翻訳されないという副作用も産み出しています。

なお、GitHub API クライアントには Jenkins 作者でもある @kohsukekawa さんの kohsuke/github-api を使わせて頂きました。

翻訳文のコピー

続いて、変更がなかった箇所の対策です。

上記した通り、再度翻訳するのは無駄なので、以前は手作業でコピーしていたのですが、@seratch_ja さんに「これ苦行ですね」と言われたので、翻訳文をコピーするツール を作りました。

@seratch_ja さんには Scala で書くと言ったのですが、ぼくが Scalaツールを書けるようになるまでの間に Play Framework 5 くらいになってしまいそうだったので、Java で書いています。

それから、少しくらい間違っていてもすぐに直せばいいじゃない、という間違ったアジャイル開発信者のような大らかな気持ちで作ったので、ひとつのドキュメント内に同じ文章が複数回登場するとコメントアウトが壊れたりと、微笑ましい動作をします。直します。

まとめ

本家サイトで公開されている翻訳プロジェクトなどと聞くと敷居が高く感じられるかもしれませんが、実際は手作業による温もり感溢れるプロジェクトであることがお分かり頂けたのではないでしょうか。

本来は Google Translation Toolkit などを使うべきだったのですが、過去の経緯 (主に無知) などにより、上記した方法で何とか運用しています。

運用改善にご協力頂いた @masahito さん、@seratch_ja さん、それから紹介が遅れましたが 翻訳ガイドライン を書くように薦めてくださった @kawachi さん、そして GitHub API クライアントを OSS で公開してくださっている @kohsukekawa さんに、この場を借りて改めてお礼を申し上げます。

本当にありがとうございます。今後ともよろしくお願いいたします。以上です。

ドキュメント翻訳の手順

この記事は Play framework Advent Calendar 2014 - Adventar の三日目です。

四日目の立候補者がいないので誰か書いてください。

おまえ誰

2010 年 4 月から Play Framework のドキュメントを翻訳しています。

以前は http://www.playframework-ja.org/ に Play 1.2 で書いたアプリをデプロイして翻訳ドキュメントを公開していましたが、現在は https://www.playframework.com/documentation/ja/ で公開しています。

が、まったく手が足りていないので、この場を借りてドキュメント翻訳の具体的な手順を紹介することで、ひとりでも多くの人に手伝ってもらえたらいいなと思っています。

概要

Play Framework 2.x のドキュメントは Markdown 記法 で書かれており、 GitHub で管理されています。

翻訳版も GitHub で管理しており、こちらの例 のように、原文をコメントアウトして翻訳文を併記しています。

ちなみに Play Framework 1.x のドキュメントは textile 記法 で書かれていますが、こちらはコメントアウトができないので、こちらの例 のように翻訳文だけ書いていました。

playframework.com は翻訳版の GitHub リポジトリを定期的にポーリングしていて、翻訳版リポジトリに取り込まれた内容は、すぐに playframework.com に反映されます。

ドキュメント翻訳の手順

おおまかな手順は 翻訳ガイドライン に書いてあるので、まずはこちらを参照してください。

以下、もっとも簡単なパターンの手順を紹介します。

例えば 2.3.x/JavaActionsComposition に未翻訳箇所を発見したとします。 f:id:garbagetown:20141204010410p:plain

ページフッタにあるドキュメントソースへのリンクをクリックします。 f:id:garbagetown:20141204010449p:plain

GitHub のページが開くので、ログインします。 f:id:garbagetown:20141204010857p:plain

翻訳する前に他の誰かが作業着手していないことを確認してください。ファイル名などで issues を検索します。 f:id:garbagetown:20141204011139p:plain

コメント欄に作業着手する旨が書かれていなければ、自分が作業する旨をコメントしてください。内容はなんでも構いません。 f:id:garbagetown:20141204011412p:plain

いよいよ翻訳します。ここでは GitHub 上のエディタで作業します。ドキュメントソースのページに戻り、編集ボタンをクリックします。 f:id:garbagetown:20141204011532p:plain

編集が完了したら、コミットコメントに issues の番号を入力して Propose file change ボタンをクリックします。 f:id:garbagetown:20141204011733p:plain

自動的にリポジトリが fork され、Pull Request の作成画面が表示されるので、Create pull request ボタンをクリックします。基本的な作業はこれで終わりです。 f:id:garbagetown:20141204011852p:plain

最後に、playframwork-ja グループのメンバーが Pull Request の内容をレビューし、問題なければマージします。 f:id:garbagetown:20141204012025p:plain

マージが完了したら、10 分以内に playframework.com に変更が反映されます。 f:id:garbagetown:20141204012155p:plain

まとめ

ちょっとした翻訳や修正の場合、GitHub のアカウントさえあれば、どなたでも簡単にご協力頂けることがお分かり頂けましたでしょうか。

Play Framework 2.3.x の翻訳は、まだまだ issues が残って います。どうぞお気軽にご協力ください。

あと、四日目のアドベントカレンダーを誰か書いてください。以上です。

JJUG CCC 2014 Fallに行ってきた #jjug_ccc

去る 11/15(土) に開催された JJUG CCC 2014 Fall に参加してきましたので、遅くなりましたが感想文。

場所は前回と同じ西新宿ベルサーレでしたが、今回は来場者数 450 名以上とのことで、各セッションで立ち見が続出し、次回から会場を変えないといけないんじゃないかと心配になる盛況っぷりでした。

参加したセッションは以下の通り。

懇親会、二次会も参加してきました。

K-1 基調講演1

JJUG 副会長の橋本さんによる基調講演。

クラウド人工知能などの技術により変化していく社会において、Java エンジニアはどのように生きていくべきかというお話で、多くの資産があって堅牢な Java はこれからの時代に強いのでチャンスですよ、と。

本業のためか AI の説明が異常に充実している印象もありましたが、時代の変化と Java を絡めた話の展開、コミュニティを盛り上げる強いメッセージが圧巻の基調講演でした。

K-2 基調講演2

続いて Oracle の Simon Ritter による基調講演。スライドはまだ公開されていないようです。

個人的に印象に残ったのは、Java とは

  • プラットフォーム
  • コンピュータ言語
  • ライブラリセット
  • 仮想マシン
  • コミュニティ

であるというお話。

コンピュータ言語としては叩かれることの多い Java ですが、JVM の堅牢さと Oracle という超大企業によるサポート、そして JCP や JSR によるオープンな仕様策定プロセスの存在など、盤石な安定感を改めて感じました。

それと、通訳の方の声がイケメン過ぎでした。

H-1 Javaが見るニュータイプの夢 ~これからJavaはどう変わるか~

きしださん。スライドのインパクトすごい。

スライドのゆるふわ感とは裏腹に、内容はとてもハードボイルドな Project Valhalla と Project Panama のお話。

Valhalla と Panama の概要は下記きしださんのブログで把握していたつもりでしたが、より詳しく理解することができました。

なんだか地味だなと思っていた Valhalla と Panama が一気に興味深いものになった素晴らしいセッションでした。

そういえば Project Coin の Collection Literals を早く、と思って調べてみたら ValueTypes を出す前に試すべきじゃないと言うことになっているようですね。

Valhalla が Java 10 だとすると Collection Literals は Java 11 くらいでしょうか・・・

R1-2 Spring Boot + Doma + AngularJSで作るERP(統合基幹業務システム)

福岡から参戦の松崎さん。

Teeda + S2Dao で IE6 対応・・・ウッ、アタマが・・・。その後 Play Framework 1 も検討されたとのことで、共通の話題が多く、懇親会で話し掛ければ良かったです。

Doma は S2 時代の遺産と勝手に思い込んでいたのですが、GitHub で開発が続けられていました。

SQL ごりごり書きたい派にはおすすめとのこと。Domaググると S2 のページがトップに来てしまうのが勿体ないですね。

Angular は名前を聞く機会が増えてきましたが、どなたもベストプラクティスを模索している印象があります。まだ手を付けられていないので、しばらく成り行きを見守りたいと思います。

R5-3 Spring Bootハンズオン~Spring Bootで作るマイクロサービスアーキテクチャ

槙さんの上級者向けハンズオン。

縁あってチューターを担当させて頂いたのですが、

というわけで、ほとんど出番はありませんでした。ようやく「すみません」と声を掛けられて、出番だ!と振り返ったら @mike_neck さんだったり。

生き残るのに必死で何が起きているか掴み切れなかった方も多いと思いますが、当日はスキップされてしまった演習 2 も面白いので、完走できた方もできなかった方も、ご自宅でもう一度ゆっくり復習されるとよいと思います。

それから、はじめての Spring Boot を買うといいと思います。

R1-5 JavaでやってみるThe Twelve-Factor App

ビズリーチ渡辺さん。徹底的なタイムマネジメントとリクルーティングがすごい。

Twelve-Factor App は以前に目を通したことがありましたが、現場で実践されている方の具体的なお話は説得力が違いますね。標準出力ログ、OS 環境変数、ビルド/リリース/実行のあたりがとくに勉強になりました。

また、議論が分かれるところだと思いますが、Play Framework に育てられたステートレス派としては Sticky セッションには反対です。パフォーマンスが超重要なサービスでない限り、cookie に乗らないくらい大きな情報は memcached が無難かと。

番外編の .war, web.xml, JSP 禁止には全面的に賛成です!!1

R2-6 ElasticsearchとKibanaではじめる検索&アナリティクス

Elasticsearch 大谷さん。

あっという間に全席埋まって立ち見。

ELK Stack ばりばりのお話かと思いきや、前半は検索に関する基本的な技術のお話も多く、とても楽しかったです。日本における Fluentd の人気を所々でネタにされていました。

また、Elasticsearch クラスタモニタリングツール Marvel やクエリ実行コンソール Sense も紹介されていました。Kibana を作った Elasticesearch 製だけあってどちらも見た目がかっこいいです。開発目的の場合は無償とのこと。

Kibana 4 のデモも紹介されていました。残念ながら背景が白いですが、そのうち黒くなるはずです、とのこと。Kibana と IntelliJ IDEA はやっぱり黒背景ですね。

R5-7 JSR 371 MVC 1.0を通じてAdopt a JSRを知ろう!

最後はどのセッションを聴くか非常に迷ったのですが、Simon の基調講演絡みで Adopt a JSR へ。

いま使っている MVC フレームワークのアンケートがあったのですが、厳しい現実が浮き彫りになっていました。

前半は宮川さんがそもそも JSR や JCP とは何かを説明した後、Adopt a JSR を紹介。

後半は槙さんが MVC 1.0 の経緯と JJUG の貢献について紹介されていました。

その後のフリーディスカッションでは JSF と REST の相性の悪さが指摘され、やはり MVC は必要という論調が強かったように思います。

個人的に JSF が肌に合わないので MVC 自体は歓迎ですが、Jersey MVC でいいじゃんという気も・・・

懇親会

Oracle 寺田さんのご好意でボールペン、キーホルダー、ステッカーなどがもらえるじゃんけん大会が開催されました。狙いすましてデュークキーホルダーをゲット。

いつも通り、みなさんあともう一本がんばってください、余ったビールは必ず持ち帰ってください、などのアナウンスが飛び交う中、缶ビールを四本くらい飲んで、三本くらい持ち帰ってきました。これで会費が 1,000 円ってどうなっているんだろう。

二次会

終電のため一時間ほどしかいられませんでしたが、二次会も参加。

まとめ

いろいろな材料とタイミングが重なり、Java が再び勢いを取り戻していることがありありと感じられるカンファレンスでした。

Java 8 のリリースからまだ間もないにも関わらず、Lambda 式や Stream API は当たり前のものとして受け入れられており、改めてこれらを取り上げるセッションは多くなかったようです。

一方で、多くのセッションが Spring Boot について触れていました。長く積み上げてきた Spring Framework の周辺技術を魔法のようにまとめあげるだけでなく、2014 年 No.1 バズワードに輝きそうな Microservices architecture との相性の良さもあり、先進的な Java エンジニアたちに受け入れられているようでした。

まだしばらく Java の盛り上がりは続くと思われるので、勉強会やカンファレンスなどに積極的に参加して刺激を受けたいと思いました。

最後に、参加者が増え続ける JJUG CCC の運営各位、本業の合間を縫って発表資料を準備された登壇者各位、本当にありがとうございました。次回も参加します。

#怖くないScala勉強会 に行ってきた

2014 年 10 月 10 日にリクルートメディアテクノロジーラボさんで開催された #怖くないScala勉強会 に参加してきました。

きっかけはこちらの何気ないひと言で、ここからわずか一ヶ月で企画をまとめて、会場と飲食物の手配をしてくださった運営各位には圧倒的感謝の気持ちしかありません。本当にありがとうございました。

感想

本日の内容は、事前準備からカリキュラム、学習の要点まで、すべて GitHub 上に公開されています。入門的な内容がコンパクトにまとまっているので、参加できなかった方も目を通して、手を動かしてみると楽しいと思います。

Google スプレッドシートの座席表で進行を管理するという方法も面白いなと思いました。

時間の関係で最後まで辿り着けませんでしたが、何でも知っているのに何も知らない初心者の気持ちが分かる @gakuzzzz 先生の説明はとても分かり易く、チューター各位の対応も丁寧で、看板に偽り無しの怖くない Scala 勉強会でした。

また、えらく軽いノリで東京まで来たなあと思ったら、いつの間にか失職していた @daiksy さんの LT もありました。

最後にピザとビールでご歓談。

play_ja のステッカーをたくさんの人がもらってくれて、とてもうれしかったです。間もなく 2.2.0 の翻訳を完了して、2.2.4 と 2.3.5 の翻訳を同時に進めようと計画しています。翻訳も怖くないのでお気軽にお手伝い頂ければと思います。

まとめ

おまけ

ファミコンで対戦しているように見えますが、カリキュラム作成中の @mike_neck さんと @gakuzzzz 先生です。

#ScalaMatsuri に行ってきた

去る 2014 年 9 月 6 日と 7 日に、日本最大級の Scala カンファレンス ScalaMatsuri に参加してきました。

昨年の Scala Conference では Typesafe 社 CTO や Play リードプログラマなどを招待していましたが、今年の招待講演はなんと Scala の生みの親である Martin Odersky 先生ということもあってか、6,000 円の有料イベントにも関わらず、あっという間に完売したそうです。

一日目

当日の様子はニコ生タイムシフトで視聴することができます。両会場とも視聴回数が 130,000 回以上と、すごいことになっています。

私は当日、S-1, S-2, A-1, A-2, S-3, A-3, B-4, B-5, S-4, B-6, B-7, A-8, A-9 を拝聴しました。どの裏番組も気になっていたのでニコ生タイムシフトはとてもありがたいです。ドワンゴ様に感謝しつつ、少しずつ観ていこうと思います。

各セッションの間隔が短かったため、後半はかなり疲れましたが、懇親会のビールとピザで気合いを入れ直して LT に登壇してきました。

途中なぜかスクリーンが何度か映らなくなるトラブルに見舞われるも、すっかりできあがっている皆さんの応援のおかげで、そこそこうまく話せたのではないかと思います。

その後、この日のために作った日本 Play Framework ユーザー会のステッカーを小田好先生に誕生日プレゼントだと言って押し付けて、一緒に記念撮影。

f:id:garbagetown:20140911233828j:plain

ステッカー作成に協力してくれた大庭ちゃん、ありがとう!

二日目

二日目は参加者から意見を募ってテーマを決めるアンカンファレンス形式。以下の URL でタイムテーブルを見ることができます。

午前中はPlay Framework のドキュメント翻訳に協力してくださる方を募り、サイバーエージェント様のミーティングルームでもくもく翻訳会を開いてみました。

限られた時間の中だったので数は少ないですが、以下のドキュメント翻訳を新たに公開することができました。ご協力頂いた佐藤さん、小林さん、ありがとうございます!

また、ファシリテーターである自分の準備不足で、せっかく足を運んでくださったのに作業をお願いできなかった方々、申し訳ありませんでした。もっと気軽にお手伝い頂ける準備を整えてから、改めてご連絡差し上げますので、そのときはまたご協力よろしくお願いします。

その後、パネルディスカッションなどを聞いて閉会。運営スタッフの方々とビールを飲みに銀座ライオンへ。

まとめ

昨年時点では業務に Scala を使うこと自体にややチャレンジングな印象がありましたが、現在では単なる選択肢のひとつとして挙げられるようになったと感じました。特にアドテクやビッグデータなど、Web アプリケーション以外の分野における存在感がとても強いと感じました。

また、個人的には登壇された皆さんのスライドに Play Framework のロゴがばんばん貼られているのが印象的でした。四年前の社内勉強会で Play Framework のドキュメント翻訳を始めたと発表したときには、とても想像できない状況です。登壇された皆さんのうち、ほんの一部の方でも翻訳ドキュメントをご覧になり、業務に活かされているのだとすれば、こんなにうれしいことはありません。

とは言え、懇親会 LT のスライド後半にも書いたとおり、ドキュメント翻訳などと言ってはいるものの現時点の私の Play2 および Scala に関する知識は極めて限定的なものです。今後はこれまで翻訳に掛けてきたリソースをもう少し技術的な面に割り振りたいと考え、懇親会 LT に応募し、翻訳協力者を募り、アンカンファレンスで手を上げました。

これから少し時間を掛けて、もっと気軽に翻訳にご協力頂ける仕組みを用意する予定です。その仕組みがうまく回り始めたら、もっともっと Play2 と Scala を勉強して、来年の ScalaMatsuri では Scala プログラマとして及ばずながらも運営のお手伝いをさせて頂きたいと考えています。

最後になりましたが、この日のために多大な時間を削って準備されてきた運営スタッフの方々、会場を提供してくださったサイバーエージェント様、ニコ生を放送してくださったドワンゴ様、スポンサー企業様、登壇者各位、初めましての方々、お久しぶりの方々、楽しい時間をありがとうございました!今後もよろしくお願いします :-)

最後の play gae:deploy

playframework の日本語ドキュメントが本家にマージされることになったので、GitHubリポジトリplayframework-ja/translation-project に引っ越したり、このへん を見ながら build.sbt を書いたりしていました。

ちなみにこのドキュメントには不備があって、build.sbt に以下を追記しないとビルドできません。

resolvers += "Typesafe Releases Repository" at "http://repo.typesafe.com/typesafe/releases/"

無事にビルドが通るところまで確認して James Roper に連絡したので、以後は上記リポジトリに翻訳文をコミットすると 10 分くらいで www.playframework.com に反映されるはずです。

最後の play gae:deploy

これで www.playframework-ja.org は晴れてお役御免となったので、サイトトップに注意書きと本家サイトへのリンクを追加しました。ドキュメントページにアクセスした場合は、リクエストされたバージョンとページ ID もリンクに埋め込まれる親切仕様です。

これを play gae:deploy という世界で 100 人くらいしか使っていそうにないコマンドで Google AppEngine にデプロイします。もう使うこともないと思うので記念にログを全文掲載。

# garbagetown at MBA-2.local in ~/devel/repos/playdocja on git:master o [9:20:45]
$ play gae:deploy
~        _            _ 
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/   
~
~ play! 1.2.7, http://www.playframework.org
~
~
~ Compiling
~ ---------
CompilerOracle: exclude jregex/Pretokenizer.next
Listening for transport dt_socket at address: 8000
09:20:53,107 INFO  ~ Starting /Users/garbagetown/devel/repos/playdocja
09:20:53,113 WARN  ~ Declaring modules in application.conf is deprecated. Use dependencies.yml instead (module.gae)
09:20:53,114 INFO  ~ Module gae is available (/Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0)
09:20:54,213 WARN  ~ 
09:20:54,213 WARN  ~ Google App Engine module
09:20:54,213 WARN  ~ ~~~~~~~~~~~~~~~~~~~~~~~
09:20:54,213 WARN  ~ No Google App Engine environment found. Setting up a development environement
09:20:54,280 WARN  ~ 
09:20:54,280 INFO  ~ Precompiling ...
09:21:05,488 INFO  ~ Done.
~
~ Packaging
~ ---------
~ Packaging current version of the framework and the application to /var/folders/w7/m65h4t_j3pj6njq64v_3dygc0000gn/T/playdocja.war ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0/lib/appengine-agent.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0/lib/appengine-agentimpl.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0/lib/appengine-agentruntime.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0/lib/appengine-api-labs.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0/lib/appengine-api-stubs.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0/lib/appengine-local-runtime.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/modules/gae-1.6.0/lib/appengine-testing.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/framework/lib/mysql-connector-java-5.1.20.jar ...
~ Excluding JAR /Users/garbagetown/devel/play/play-1.2.7/framework/lib/postgresql-9.0.jar ...
~
~ Deploying
~ ---------
********************************************************
There is a new version of the SDK available.
-----------
Latest SDK:
Release: 1.9.9
Timestamp: Wed Aug 06 10:10:14 JST 2014
API versions: [1.0]

-----------
Your SDK:
Release: 1.9.6
Timestamp: Fri May 30 09:53:36 JST 2014
API versions: [1.0]

-----------
Please visit https://developers.google.com/appengine/downloads for the latest SDK.
********************************************************
Reading application configuration data...
Aug 23, 2014 9:21:18 AM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml
INFO: Successfully processed /var/folders/w7/m65h4t_j3pj6njq64v_3dygc0000gn/T/playdocja.war/WEB-INF/appengine-web.xml
Aug 23, 2014 9:21:18 AM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
INFO: Successfully processed /var/folders/w7/m65h4t_j3pj6njq64v_3dygc0000gn/T/playdocja.war/WEB-INF/web.xml


Beginning interaction for module default...
0% Created staging directory at: '/var/folders/w7/m65h4t_j3pj6njq64v_3dygc0000gn/T/appcfg6862628993578567634.tmp'
5% Scanning for jsp files.
20% Scanning files on local disk.
25% Scanned 250 files.
28% Scanned 500 files.
31% Scanned 750 files.
Aug 23, 2014 9:21:57 AM com.google.appengine.tools.admin.AppVersionUpload addFile
SEVERE: Invalid character in filename: WEB-INF/application/public/images/layout/right-fake-column@2x (1).png
33% Scanned 1000 files.
34% Scanned 1250 files.
Aug 23, 2014 9:21:57 AM com.google.appengine.tools.admin.AppVersionUpload addFile
SEVERE: Invalid character in filename: WEB-INF/application/bin/public/images/layout/right-fake-column@2x (1).png
35% Scanned 1500 files.
36% Scanned 1750 files.
37% Scanned 2000 files.
37% Scanned 2250 files.
37% Scanned 2500 files.
37% Scanned 2750 files.
37% Scanned 3000 files.
37% Scanned 3250 files.
37% Scanned 3500 files.
37% Scanned 3750 files.
37% Initiating update.
37% Cloning 3805 application files.
37% Cloned 2000 files.
40% Uploading 441 files.
52% Sending batch containing 100 file(s) totaling 2342KB.
61% Uploaded 110 files.
68% Sending batch containing 100 file(s) totaling 2513KB.
73% Uploaded 220 files.
77% Sending batch containing 100 file(s) totaling 2470KB.
80% Uploaded 330 files.
82% Sending batch containing 100 file(s) totaling 2843KB.
84% Uploaded 440 files.
85% Initializing precompilation...
86% Sending batch containing 41 file(s) totaling 1015KB.
90% Deploying new version.
95% Closing update: new version is ready to start serving.
98% Uploading index definitions.

Update for module default completed successfully.
Success.
Cleaning up temporary files for module default...
~ 
~ Done!
~ 

テストと切り替え

無事にデプロイが完了すると GAE コンソールの Versions というメニューに appengine-web.xml で指定したバージョンのアプリケーションが増えています。

f:id:garbagetown:20140823095350p:plain

バージョン番号.アプリケーションID.appspot.com という URL で特定バージョンのアプリケーションにアクセスできるので、内容を適当にチェックして

f:id:garbagetown:20140823100840p:plain

問題が無いことを確認できたら、こちらのバージョンをデフォルトにします。

f:id:garbagetown:20140823100938p:plain

www.playframework-ja.org で最新版にアクセスできることを確認して作業おわり。

f:id:garbagetown:20140823101030p:plain

四年間ありがとう。お疲れさまでした。

Spring Boot 入門ハンズオンに行ってきた #jggug_boot

Groovy ユーザーグループのイベントでタイトルに Grails とありながら groovy も grails も gradle も使わないハンズオンに行ってきました。

157 ページに及ぶ入魂のスライドはこちら。

所感

  • 一日分くらいの内容を二時間で駆け抜ける超高濃度ハンズオン
  • Web サービスを上手かつユニークに活用
    • 入力するコードはすべて gist にアップロードされていて、スライドに貼られた bit.ly の URL をクリックしてコピペすれば OK という至れり尽くせり仕様
    • Same Origin Policy を突破する Filter を設定して JSFiddle から localhost にアクセスできるようにするという発想はなかった
  • Spring Boot とてもいい
    • ログが見易い
    • jar に固めたあとでも外からプロパティを変更できる
    • YAML で設定が書ける
    • 依存性に starter を追加するだけで「いい感じ」にコンポーネントが登録される
      • 多数の starter が用意されている
      • 自分で starter を作ることもできる?
    • asset pipeline がほしい
  • Spring Loaded がんばれ
  • TERASOLUNA Global Framework Development Guideline を読みましょう

まとめ

DI コンテナ単体としては Seasar2 と比べて冗長で堅苦しい印象があり、プロジェクト全体としては JavaEE と同じくらい多様で複雑な印象があった Spring Framework ですが、Spring Boot の登場で急に The Twelve-Factor App に書かれているような近代的アプリケーションを開発できるプラットフォームに化けたと感じました。

良くも悪くも過去の資産を切り捨てていないので、放っておいてほしいのに定期的に寄ってきて Java を dis って帰っていく怖い人たちに突っ込まれるポイントはいくつか見受けられるものの、現実的な落としどころだと思います。後方互換性を堅持しながら、なんとか Stream API や Lambda 式を提供するに至った Java8 のような印象です。

Spring 周りはもともとドキュメントがとてもよく整備されていますし、今回のハンズオン資料や上記ガイドラインに加えて書籍も執筆中とのことで、日本語情報も充実しています。

Spring Boot 自体はまだまだ開発が活発とのことなので、大規模案件には向かないかもしれませんが、ようやく名実共に終了という雰囲気になった Struts 先輩の後釜として検討する価値は充分にあると思いました。

ハンズオン中級者編も開催予定とのことで、とても楽しみです。

あわせて読みたい

追記

asset pipeline についてさっそく @making さんからフォロー頂きました。

URL の読み替えや物理パスとの紐付けなどはサーバサイドで解決すべきことなので Resolver と Transformer を用意するけど、静的リソースの変換や結合、ミニファイなどは grunt や gulp を使ってクライアントサイドで実施するよう整理したとのことです。

この辺りは HTTP/2 や ECMAScript 6 の登場でがらっと状況が変わるはずだから、とも書かれており、納得です。