Qiitaのブログパーツのカスタマイズ&設置

伊藤さんのブログの「Qiitaのブログパーツをはてなブログのサイドバーに設置する方法」を参考に、便乗してこのブログのサイドバーにもQiitaのブログパーツを貼り付けてみました。

同じく、@suinさんの作られているQiita Widgetをカスタマイズしています。

カスタマイズしたのは以下の点。

  • 表示件数を10件→5件に。
  • フォントのスタイルを変更。font-familyはこのブログのfont-familyをそのまま利用し、非boldにしました。
  • ブログパーツのヘッダ部分のバーを削除。削除した経緯:
    1. font-familyを定義したら、コンパイル後の script.js がエラーになってしまった*1
    2. そこで、 script.js の圧縮は行わないようにした。
    3. 圧縮を行わないので、なるべくスクリプトサイズを抑えるため、バーを削除*2

フォークしたリポジトリのREADMEに、コンパイル手順のメモを書いています。

https://github.com/tq-jappy/qiita-widget

ちなみに、ChromeFirefoxでしか確認していないので、IEでは見られるか不明…。また後で直そう…。

Qiita Widgetを作られた@suinさん、参考にさせていただいた伊藤さん、ありがとうございました。

*1:詳しく見ていないのですが、圧縮後のscript.jsに対して<!--%css%-->を置換するところでポカしてそうなので、単純にlessの書き方が悪いだけの可能性大です。

*2:バーに表示するQiitaのロゴ(Base64での画像埋め込み)が比較的容量を食っていたので。

いいコードをみんなで書く

Keynoteに慣れるために、適当なスライドを作ってアップロードしてみました。

このスライドは、1年くらい前にチームで行ったLT大会の初回に発表したテーマです。プログラミングをする上で考えていることとか、これまでの反省点とか、LTみたいな場がないと話さないであろうことを話した、気がします。

当時はGoogleドキュメントのプレゼンテーションで作ったんですが、それをリメイクしました。旧スライドは「今でしょ!」で締めていたのですが、さすがに時期を過ぎたので破棄しましたw

中身が薄いのと、自分でも全然できていないことを偉そうに書いてるのは相変わらずですね…orz

Keynoteのテンプレートはsanographixさんの「Azusa」を利用させていただきました。すばらしいテンプレートをありがとうございます!

続きを読む

Dropwizard 0.7.0でWebSocket

Dropwizard 0.7.0では組み込みWebサーバとしてJetty 9.0.7が使われており、Jettyであれば非Java EE7環境でもWebSocketが使えるはずだと思ったので、一番簡単なechoを作って試してみました。

build.gradle

まず、websocket-server への依存関係を追加します。

compile 'org.eclipse.jetty.websocket:websocket-server:9.0.7.v20131107'

これで、推移的な依存関係により、websocket-commonwebsocket-clientwebsocket-servlet が追加されます。

WebSocketクラスの作成

@org.eclipse.jetty.websocket.api.annotations.WebSocket アノテーションをつけたPOJOを作ります。

package example.websocket.echo;

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;

@WebSocket
public class EchoWebSocket {

    @OnWebSocketConnect
    public void onConnect(Session session) {
        // do nothing
    }

    @OnWebSocketMessage
    public void onText(Session session, String message) {
        session.getRemote().sendStringByFuture(message);
    }

    @OnWebSocketClose
    public void close(Session session, int statusCode, String reason) {
        // do nothing
    }
}

今回のメインロジックですが、これだけです。メッセージを受け取った処理は@OnWebSocketMessageアノテーションをつけたメソッドで実装し、受け取ったメッセージをそのまま同じクライアントに送るようにしています。

ちなみに、このように@WebSocketクラスを作る方法と別の方法として、org.eclipse.jetty.websocket.api.WebSocketListener インタフェースを実装する方法もあるみたいです。

アプリケーションクラスにWebSocketHandlerをセットする

io.dropwizard.Applicationを継承して作ったアプリケーションクラスの run メソッドを修正。

アプリケーションコンテキストにWebSocketHandlerを追加し、先ほど作った EchoWebSocket クラスを登録します。

environment.getApplicationContext().setHandler(new WebSocketHandler() {

    @Override
    public void configure(WebSocketServletFactory factory) {
        factory.register(EchoWebSocket.class);
    }
});

今回一番頭を悩ませたのがこの辺り。最初は WebSocketServlet を作って登録させてみたのですが、うまく動かず、色々試行錯誤した結果、この方法に落ち着きました。

クライアントの作成

JavaScriptでオーソドックスに書きます。

  var ws = new WebSocket("ws://" + location.host + "/");

  ws.onopen = function(event) {
      console.log("connected.");
      ws.send("hello!");
  }

  ws.onmessage = function(event) {
      console.log("message received from server.");
      console.log(event.data);
  }

HTMLでの見せ方は色々(省略)。

一通り書いたらあとはいつも通り ./gradlew jar でビルドしてアプリケーションを起動後、 http://localhost:18080 にアクセスすれば、ブラウザのコンソールログとしてサーバからエコーバックされた "hello!" が出力されると思います。

補足

今回のJettyのバージョンは9.0.7ですが、9.1からは、JettyのWebSocket対応がJSR 356ベースに変わっているみたいです。逆に言うと、Jetty9.0.7のWebSocket対応はJava標準のものではなく、JettyのAPIに依存した形になっています。そのため、今後Dropwizardが対応するJettyのバージョンが9.1以上になれば、ここでの記事の情報は古くなります。

ちなみに最初はJSR 356の参照実装であるTyrusを試したのですが、断念しました。。

参考

Dropwizard0.7.0でのassets

Dropwizard続き。

Dropwizardで作るアプリケーションのビューとしては、「Dropwizard Views」にあるように、FreeMarkerとMustacheが使えるみたいなのですが、せっかくJAX-RSベースのRESTfulアプリケーションを開発しているので、ビューとロジックは分けたいなと思いました。ビュー側で、Javaへの依存を抑えて、いわゆるSingle Page Application(SPA)を作るための下地を作ります。

Dropwizard0.7.0の場合、以下のようになります。

  • dropwizard-coreにはdropwizard-assetsへの依存関係が含まれていないので、 build.gradle に追加(dropwizard系のライブラリの構成が整理されたのも0.6→0.7での変更点の一つ)。
compile 'io.dropwizard:dropwizard-assets:0.7.0'
  • src/main/resource 以下に assets ディレクトリ(名前は設定次第なので何でもよい)を作り、 index.html を配置(中身は確認ができる最低限のもの)。
  • Applicationクラスの initialize メソッド内で AssetsBundleaddBundle する。 AssetsBundle には5パターンのコンストラクタがあるのですが、 AssetsBundle で定義されているデフォルトのインデックスファイルのファイル名が index.html ではなく index.htm なので、 index.html にさせるために必要なパラメータを全て渡しています。
public void initialize(Bootstrap<HelloAppConfiguration> bootstrap) {
    bootstrap.addBundle(new AssetsBundle("/assets", "/app", "index.html", "assets"));
}

「qpstudy 2014.04 ~俺の屍を超えて行け、でも踏まないで~」をニコ生で観た

140文字にきれいに収まらないかもしれないので(きれいに収まっていないのはいつもだけどw)、こっちに感想を残しておこう。

qpstudy 2014.04 ~俺の屍を超えて行け、でも踏まないで~」がニコ生で観られるとのことだったので、昨日観てました(途中からですが)。

こういう勉強会をニコ生で観るのは初ですが、視聴環境も快適でした。ドワンゴさんまじドワンゴ

僕は開発よりの人間ですが、#qpstudyは動向をネットで追っかけるくらいのことはしていて、ちょうど今回、

初心者とは、インフラエンジニア業務2年未満、もしくはインフラエンジニアでは無い方を指します。

とのことだったので、インフラエンジニアでは無い立場の初心者として視聴し、勉強させてもらいました。途中ほとんど理解できない部分もあったけど、それを知ることができたのもまた勉強。その辺は僕の知識不足で、全体通してとても分かりやすく、楽しい発表でした。ライトスルー、ライトバックとか、情報処理技術者試験(タイムリーなネタを話題に出しておこう)くらいでしか聞いたことなかったしね。

あとは、作ったアプリケーションがリリースされてから、インフラエンジニアが何を考えて、どんなことをしてるのかとか、あまり普段の業務で知る機会がなかったし、割とリアルな声を聞くことができてよかったです。自分の立場は、完全にアプリケーション開発というだけではなくて、APサーバ、DBサーバみたいなミドルウェア周りとか、シェルスクリプトをがりがり書くみたいなこともやってたりだけど、ネットワークやOSのレイヤも含めての全体像はなかなか見えてなかったので、いいきっかけになりました。

アプリケーション開発する際でも、ユーザはもちろんのこと、インフラエンジニアのことも考えてアプリケーションは開発しないといけないなってことと、(流行りのツールやフレームワークも大事だけど)やっぱり基礎は大事だなってことを考えさせられました。

DropwizardでWebアプリケーションを作る

調べものをしていたらたまたまDropwizardを見つけたので試してみました。

Dropwizardとは?

Dropwizard is a Java framework for developing ops-friendly, high-performance, RESTful web services.

公式サイトにある通り、「運用に優しく、ハイパフォーマンスな、RESTful Webサービスを作るためのJavaフレームワーク」のようです。

依存関係としてdropwizard-coreを一つ追加すると、Jetty, Jersey, Guava, Logback/slf4jなどのよく使うライブラリが含まれます。

単純な実行(アプリケーションの起動)なら、Javaがインストールされている環境なら、ビルドしたjarファイルと設定ファイルがあれば、 java -jar {jar file} server {configuration file} で終わりです。現実的にdaemonizeとかサービス起動したい場合は少し手を加える必要があるかも。

作ってみた

Getting Started」を写経してHello Worldアプリケーションを作りました。ただし、ビルドはMavenではなく、Gradleで行うようにしました。

https://github.com/tq-jappy/dropwizard-example

Dropwizardのバージョンは0.7.0です。

できあがったものは、@hina0118さんの「DropwizardのHello World - Qiita」のほぼ焼き直しになった(ただし@hira0118さんの例はバージョン0.6.2)ので、0.6.2と0.7.0の間の差分だけメモしておきます。

リポジトリ

build.gradle

  • 0.6.2
  compile 'com.yammer.dropwizard:dropwizard-core:0.6.2'
  • 0.7.0
  compile 'io.dropwizard:dropwizard-core:0.7.0'

パッケージ

com.yammer.dropwizard -> io.dropwizard

一部クラス名やAPIの変更などもあります(公式が最新バージョンに追随しているのでそちらを参照)

起動ポートを変更

デフォルトの設定では8080番ポートでアプリケーションが、8081番ポートで管理メニューが立ち上がるのですが、このポートは何かと被ることが多いので、設定ファイルを以下の通り変更しました。

template: Hello, %s!

defaultName: Stringer

server:
  applicationConnectors:
    - type: http
      port: 18080
  adminConnectors:
    - type: http
      port: 18081

この辺の設定の仕方も0.6→0.7で大きく変わっています。

ちなみに、server.type: simpleを指定した以下の書き方はうまく動きませんでした…。

server:
  type: simple
  applicationContextPath: /application
  adminContextPath: /admin
  connector:
    type: http
    port: 8080

ビルド

ビルドしたjarファイルのサイズは約10.2MBでした。軽い。

感想

Hello Worldでのつまみ食い程度ですが、第一印象はとても可能性も感じるものでした。(一部では)2014年大ブレイクと囁かれているみたいで、今後の発展に期待です。

Java EEの機能をフルに使う必要がなく、とにかくサクッと開発を始めたいなら、とてもいいですね。

あと、以前作ったJavaアプリケーションをポータビリティの高いものにしたいというのはずっと悩んでいたところだったので、Dropwizardを使えばうまくフィットしそうです。元々は、Jenkinsのように java -jar jenkins.war でアプリケーションが立ち上がる実行可能WARファイルを一から作ることを考えてました(JenkinsはWinstoneを中に持っていたんだっけ…?)。この辺りの起動の仕組みは、スクラッチで作るより、Dropwizardを使うほうがずっと簡単にできそうですね。

現実的なWebアプリケーションを作るにあたってはいくつか懸念事項(フロントエンド周り、DI、ORMはDomaを使いたい、とか)があるので、少しずつ消化していきたいです。

VeeweeでCentOS6.5のboxを作る

ただの作業記録です。

  • 以下のGemfileを作って bundle install
source 'https://rubygems.org'

gem 'veewee'
  • CentOSのテンプレートを探す
# bundle exec veewee vbox templates | grep CentOS
  • CentOS6.5が見つからないため(veewee 0.3.12時点)、CentOS6.4を選択
# bundle exec veewee vbox define centos6_64 'CentOS-6.4-x86_64-minimal'
  • boxファイルのビルドを実行
# bundle exec veewee vbox build centos6_64
  • 実行するとエラー(どうやらファイルがなくなっている模様)
http://yum.singlehop.com/CentOS/6.4/isos/x86_64/CentOS-6.4-x86_64-minimal.iso:
404 Not Found
  • CentOS6.5のminimal.isoはあるみたいなので、ISOファイルの取得情報が書かれているファイル definitions/centos6_64/definition.rb を書き換える(isoのMD5http://yum.singlehop.com/CentOS/6.5/isos/x86_64/md5sum.txt を参考にしましたが、veeweeのmasterブランチにはCentOS6.5用のテンプレートがあるみたいなので、それと差し替えてもよいと思います)
   # :iso_file => "CentOS-6.4-x86_64-minimal.iso",
   # :iso_src => "http://yum.singlehop.com/CentOS/6.4/isos/x86_64/CentOS-6.4-x86_64-minimal.iso",
   # :iso_md5 => "4a5fa01c81cc300f4729136e28ebe600",
   :iso_file => "CentOS-6.5-x86_64-minimal.iso",
   :iso_src => "http://yum.singlehop.com/CentOS/6.5/isos/x86_64/CentOS-6.5-x86_64-minimal.iso",
   :iso_md5 => "0d9dc37b5dd4befa1c440d2174e88a87",
  • リトライ
# bundle exec veewee vbox build centos6_64
  • 成功
The box centos6_64 was built successfully!
  • box作成
# bundle exec veewee vbox export centos6_64

補足

気軽にVagrantを使うのであれば、Vagrantbox.esにて公開されているものを使えばよいと思います。
今回、CentOS 5.10/6.5のそれぞれについて、x86/x86_64の組み合わせで、合計4つのboxを用意したかったのです。どのパターンのboxも公開はされているのですが、boxファイルの出処がバラバラで、「要するに何が入っているか分からなくて管理するの怖い」状態だったので、自前で素の状態のboxを用意したいと思ったのでした。

vbox build は10分ちょっとで自動で終わりますし、boxファイルは一度作っておけばずっと使えるので、許容できる範囲の手間だと思います。