eclipseを使ってvert.xを起動する

Eclipseでvert.xをローカルで起動するのに、 Gradle テンプレートを使うってのは見かけたけどmavenプロジェクトの記事があまり見当たらなかったので覚え書き。
Eclipse Java EE IDE for Web Developers.Version: Juno Service Release 2
mavenはm2eプラグインを使用。


eclipsemavenプロジェクトを作成して、Archetypeをvertxを選択する。
f:id:flick-flick:20130911015640p:plain
f:id:flick-flick:20130911015641p:plain

maven-dependency-plugin (goals “copy-dependencies”, “unpack”) is not supported by m2e

というpom.xmlのエラーが出るので
こちらの書き込みに従いタグの直下にpluginManagement以下を追記する

これでプロジェクトのエラーが消えるので、試しにfooパッケージに

package foo;
import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.platform.Verticle;

public class HelloWorldVerticle extends Verticle {
	public void start() {
		container.logger().info("Verticle start.");
		vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
			public void handle(HttpServerRequest req) {
				req.response().headers().set("Content-Type", "text/plain");
				req.response().end("Hello World!");
			}
		}).listen(8080);
	}
}

というテストコードをServer.javaという名前で置いてみる。
さらに
src/main/resources/mod.jsonの

  "main":"foo.PingVerticle",

    "main":"foo.Server",

に変更する

eclipseのプロジェクトを右クリックRunからmaven buildで起動する。
f:id:flick-flick:20130911015642p:plain
※CLIの場合はmvn vertx:runModEclipseを叩く。

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Project - testio 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- vertx-maven-plugin:2.0.0-final:runModEclipse (default-cli) @ testio ---
[INFO] CTRL-C to stop server

とかログが出るので,ブラウザからlocalhost:8080でhello worldが出ればおk

pythonでJpeg画像のexifを編集する

ある時子供を撮影するのによく使っているデジカメNEX-5の初期設定を誤ったらしく、全部の写真の日付が一年前になっていることに気づいた。

印刷する時に日付を入れる場合は全部一年ずれて日付がついてしまうので、今までNEX-5で撮った写真のexifを書き換えるためのスクリプトを書いた。



とりあえずpythonexifをいじるために調べて最初に出てきたのはPython Imaging Libraryだったが、どうやらexifを読み込む機能しかないらしい。
http://www.pythonware.com/products/pil/

pyexiv2というのがイケてるらしいのでこれでスクリプトを書くことにする。
Python で JPEG の Exif などを扱う
チュートリアル


Mac上にvagrantでubuntu12環境を用意した上でpyexiv2をインストールする

apt-get install python-pyexiv2

これで終わり。
あとはpyexiv2を使った普通にexifの日付情報を一年進めて書き換えた上で保存すればOK

import sys
import os
import stat
import datetime
import pyexiv2

targetDir = "/home/vagrant/100MSDCF_2/"
count = 0
for fileName in os.listdir(targetDir):
	f = targetDir + fileName
	s = os.stat(f)
	times = (s[stat.ST_MTIME], s[stat.ST_MTIME])
	mtime = datetime.datetime.fromtimestamp(s[stat.ST_MTIME])

	metadata = pyexiv2.ImageMetadata(f)
	metadata.read()
	dateTimeTag = metadata['Exif.Image.DateTime']
	dateTimeOriginalTag = metadata['Exif.Photo.DateTimeOriginal']
	dateTimeDigitizedTag = metadata['Exif.Photo.DateTimeDigitized']
	thumbnailDateTimeTag = metadata['Exif.Thumbnail.DateTime']

	dateTimeTag.value = dateTimeTag.value + datetime.timedelta(days = 366)
	dateTimeOriginalTag.value = dateTimeOriginalTag.value + datetime.timedelta(days = 366)
	dateTimeDigitizedTag.value = dateTimeDigitizedTag.value + datetime.timedelta(days = 366)
	thumbnailDateTimeTag.value = thumbnailDateTimeTag.value + datetime.timedelta(days = 366)

	print "convert done " + f + " ->" + dateTimeTag.raw_value
	metadata.write()
	count += 1
print str(count) + " files done"

それにしてもぱぱっとubuntuとか必要な環境を作れちゃうvagrantはほんと便利ですなー。

subversionを使ったA successful Git branching modelの運用


現在のプロジェクトではsubversionを使っているのですが、10人ほどの開発メンバーで並行開発をしているためA successful Git branching modelを参考にFeature branchesを活用した開発スタイルにしています。

A successful Git branching model を翻訳しました


しかしどうしてもブランチの統合時に意味不明なコンフリクト(競合)が発生してしまい、その度に手動(というか目視やメンバー同士の確認)でのマージを行なっておりリリースや統合が高コストになっていました。


例えば以下のような場合

2.のマージの時にfeature1ブランチにhello.jpgがコミットされたという変更履歴が残るため、3.のdevelopへのマージの際にはfeature1ブランチの変更点(コミット)を全てマージしようとするため、再度developにhello.jpgをコミットしてしまうようです。


調べた所reintegrateというオプションを見つけました。

Subversion 1.5 以降での機能ブランチのマージ

ブランチをトランクにマージするときは、--reintegrate オプションを付ける。

    • reintegrate オプションを使うこの形式のマージは一つのブランチにつき一回だけ行える (その後ブランチを更新してもそれをトランクにマージできないので、ブランチはただちに削除するとよい)。ブランチでの変更のうち、トランクからブランチへのマージによるもの以外の変更がトランクに適用され、自動的に svn:mergeinfo 属性が更新される

Eclipsesubversiveを使っている場合はマージウィンドウのタブに該当の機能がありました。

ここからマージ作業を行えば、晴れてブランチでの修正分のみがdevelopに取り込めましたとさ!


追記:
mergeの方法についてなのですがdevelop -> featureブランチへの取り込み時に手動でマージ(ファイルを上書きするとか差分エディタで書き込むとか)すると、svn管理上のmergeinfoというプロパティがセットされません。
そのため、reintegrateマージの際に上記コミットがマージコミットとして認識されずに、developへのマージ時にコンフリクトしてしまいます。

developからfeatureブランチへの取り込みの際は必ずmergeコマンド(or eclipseのマージ機能)を使うようにしましょう。
http://www.asahi-net.or.jp/~iu9m-tcym/svndoc/svn_mergeinfo.html

Ubuntu 12.04 LTS上にjsアプリケーション環境構築

  • vimとtmuxの設定ファイルをcloneして設定
git clone https://github.com/waysaku/dotfiles.git
cp ~/ ~/dotfiles/.vimrc
cp ~/ ~/dotfiles/.tmux.conf
  • vimのvundle環境構築
git clone http://github.com/gmarik/vundle.git ~/.vim/vundle.git
  • nvmインストール

ここみてインストールする

  • nvmを使ってnodeの最新版をインストール
$ nvm install v0.11.2
  • gruntインストール
npm install -g grunt-cli
  • ruby1.9とrubygemをインストール
apt-get install ruby1.9.1 rubygems
  • sassをインストール
gem install sass
  • compassをインストール
gem install compass
  • hostを書き換え
echo "[ip] [host]" >> /etc/hosts
  • ssh-key作成してGHEに登録
ssh-keygen -t rsa

備忘録

FuckなEclipsejavascriptのバリデーター機能。
利用しているライブラリのエラーとかも☓マークで指摘してくるからうざい。

しかも


いろいろな設定をオフにしても全然消えてないからさらにうざい。
毎回イラっとくるから備忘録として残しておく。

  1. Open Properties Dialog of Your Project.
  2. Choose Builders item.
  3. Uncheck "JavaScript Validator". And Press OK button.
  4. Remove current errors and warnings from Problems View

4.のProblemリストにあるエラー表示を手動で削除するってのがいつも忘れる。

visualvmをRemoteで利用する

JDK6からすげー便利なvisualvmというプロファイラが付属されています。
内容についてはこちらに詳しく書いてあるので端折ります。


このvisualvmをリモートで接続する場合はJMX経由で接続する方法とjstatdというデーモン経由で接続する方法があるようです。
どう違うのか気になったのですが私が調べた限りだと機能的には違いはないようです。
ただ、jstatsデーモンを起動しておけば、そのサーバ上で動いているそのjstatdを起動したユーザーと同じユーザー権限で起動しているjavaプロセスを全部表示することができるのでjstatdのほうがいいような気がします。
※いちいち全部のプロセスの起動スクリプトにJMXの設定いれるの面倒なので。



そんなわけでjstatdを起動しようとしたのですが、
http://d.hatena.ne.jp/tanamon/20091016/1255674058
を参考に

grant {
	permission java.security.AllPermission;
}

というall.policyを作って

jstatd -J-Djava.security.policy=all.policy &

って感じでjstatdは起動したのですが、jvisualvm側でリモート設定してもうんともすんともでした。



試しに

jps -l [jstatdが起動してるサーバのIP]

で確認してみると

Error communicating with remote host: Connection refused to host: 127.0.0.1; nested exception is: 
	java.net.ConnectException: Connection refused

なエラーが。



こちらに書かれている通りRMIの仕様上の問題っぽいので起動オプションを

jstatd  -J-Djava.security.policy=all.policy -J-Djava.rmi.server.hostname=[サーバのIP]

で起動してjvisualvmでリモート接続したら無事表示できました。

mac Lionでローカルでpostfixを起動してローカルのメールボックスに保存してみる

メールをローカルのpostfixに送信して自分で受信してローカルのメールボックスに保存するテストをしてみる
$vim /etc/postfix/main.cf

myhostname = yuhsaku.co.jp    #ローカルのpostfixのホスト名を適当に設定
mydestination = $myhostname, localhost.$mydomain, localhost    #myhostnameのドメインできたメールは自分が宛先とする


sudo postfix start

telnet localhost 25
をすると反応がなくなってしまうので/var/log/mail.logを見ると

	fatal: open /etc/postfix/submit.cred: No such file or directory

みたいなエラーが出ている。



http://tohae.hatenablog.com/entry/20110929/1317278539
で対応が書いてあったので、そのとおりにファイルを作成して2行を追加してからパーミッションを設定する

$ sudo touch /etc/postfix/submit.cred
$ sudo vim /etc/postfix/submit.cred
#この2行を追加
submitcred version 1
hostname|username|password
$ sudo chmod 600 /etc/postfix/submit.cred


これでとりあえず
http://linux.kororo.jp/cont/server/postfix.php
に書いてある通り動作確認をする。

$ telnet localhost 25
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 yuhsaku.co.jp ESMTP Postfix

helo localhost
250 yuhsaku.co.jp

mail from:
250 2.1.0 Ok

rcpt to:
250 2.1.5 Ok

data
354 End data with .

subject:hoge test
way way
.
250 2.0.0 Ok: queued as A6BD7198621F

quit
221 2.0.0 Bye
Connection closed by foreign host.

すると、すぐに以下のようなメッセージがコンソールに出てくるので

You have new mail in /var/mail/A11068


中身を見てみるとちゃんとメールがローカルに保存されていました。
cat /var/mail/a11068

From ore@test.co.jp  Mon Aug 27 21:43:47 2012
Return-Path: 
X-Original-To: A11068@yuhsaku.co.jp
Delivered-To: A11068@yuhsaku.co.jp
Received: from localhost (localhost [IPv6:::1])
	by yuhsaku.co.jp (Postfix) with SMTP id A6BD7198621F
	for ; Mon, 27 Aug 2012 21:43:13 +0900 (JST)
subject:hoge test
Message-Id: <20120827124332.A6BD7198621F@yuhsaku.co.jp>
Date: Mon, 27 Aug 2012 21:43:13 +0900 (JST)
From: ore@test.co.jp

way way


※postfixのデフォルトのメール保存形式はmbox形式なんですね