Windows Azure PowerShell Cmdlets で No certificate was found in the certificate store with thumbprint ~ が出たら

はまったのでメモ。

C:\Users\<ユーザー名>\AppData\Roaming\Windows Azure Powershell\ に入っているファイルを消して、 Set-AzureSubscription や Select-AzureSubscription をやり直すだけ。

Azure の管理画面を開いて、管理証明書の値を確認して、以下のコマンドを実行すると作り直されました。

Import-Module Azure

$subscriptionName = "<サブスクリプションの値>"
$subscriptionId = "<サブスクリプション IDの値>"
$thumbprint = "<サムプリントの値>"

$myCert = Get-Item cert:\\CurrentUser\My\$thumbprint
Set-AzureSubscription `
  -SubscriptionName $subscriptionName `
  -SubscriptionId $subscriptionId `
  -Certificate $myCert

Get-AzureService

Azure の管理証明書を変更した時に、ローカルからもその証明書を消したら発生するのかな?

自炊した PDF をドラッグアンドドロップで kobo 形式に変換

いろいろ kobo ちゃん叩かれているけど、デバイスは別に悪くないと思うんだけど。

で、こいつは自炊した PDF を奇麗に表示できない問題があるんですけど、ChainLP とか使って変換すれば読めるようにはなります。この記事がすごくわかりやすいです。

そんで、今回はこの一連の作業をお手軽にするのが目的です。(PDF より cbz 形式に変換した方が、サクサク読める気がするので cbz に変換します)

ChainLP のインストール

まずは、ChainLP をここからダウンロードして適当な場所に展開します(ここでは C:\ChainLP40b12 とします)。ChainLP.exe が起動しない場合は、.Net Framework 4 をインストールしないといけいないかもしれません。

そんで、画像ファイルを cbz に変換するために、zip3j037.lzh と zip232dN.zip をここからダウンロードしてきて展開し、ZIP32J.DLL と ZIP32.DLL を ChainLP のフォルダに入れます。

設定ファイルを作成

次に ChainLP の設定ファイルを作ります。

ChainLP.exe を起動し、サイズを 600x800 に変更します。あとは PDF の画質に合わせて、ページ補正を変更したり、本文ボールド化を設定します。一通り設定が終わったら、編集メニューにある設定の別名保存を選択し kobo.ini として ChainLP と同じフォルダに保存します。

f:id:hikoma:20120802000355p:plain

PDF から cbz にコンバートする

以上で準備は完了です。コマンドプロンプトを開き、以下のコマンドを打てば PDF から cbz に変換することができます。

c:\ChainLP40b12> ChainLP.exe -b -ini kobo.ini -i "<PDFファイル>" -o "<出力ファイル>.cbz"

コンバートをバッチファイルにする

それで、この変換をバッチファイルにするとこんな感じになりました(ダウンロード)。

この kobo.bat に PDF ファイルをドロップすれば、コンバートされて出来た cbz ファイルが kobo.bat の横に出来上がります。PDF を複数ドロップすれば、全て変換されます。

バッチの中身を簡単に説明すると、

  • CHAINLP_DIR は ChainLP をインストールしたフォルダですので、適宜書き換えてください
  • SETTING は ini ファイルの場所です。%~n0 はバッチのファイル名で kobo.bat の場合は kobo という値になり、kobo.ini が読み込まれます。ですので、ファイル名を kobo-comic.bat にすれば kobo-comic.ini の設定を使って変換できます
  • OUTPUT_DIR は cbz の出力先で %~dp0 はバッチがあるフォルダです。好きなフォルダに変更してオッケーです

おまけ

本当は ini ファイルを使わず、直接 ChainLP.exe のパラメータを指定したかったのですが、高さの指定が分からなかったのであきらめました。ChainLP.exe -h でパラメータを確認できるので、興味があればチャレンジしてください。

また、出来上がった cbz ファイルの実体は zip ファイルなので、アーカイバに関連付けておくと捗りますね。

Java と MySQL で時差を正確に扱う方法

最近は C#SQL Server を使っているので、JavaMySQL で遊ぶ時間がなくなってしまいました。ちょっと眠っていたネタがあったので忘れる前に書き残しておきます。

日時の国際化

日時の国際化というと、時差の変換が一番イメージしやすいかと思います。例えば twitter の場合、海外のツイートでも、タイムラインでは日本時間で表示されますよね?これを実装する場合、内部的には UTC 時間で保存しておいて、表示する人のタイムゾーンに合わせて時差を変換してやるのが一般的かと思います。

保存先に RDB を使う場合、WHERE で絞り込んだり、ORDER BY でソートする分には、タイムゾーン変換は不要なので、レコードを取得した後にアプリケーション側でタイムゾーン変換をすれば問題ありません。

だけど、GROUP BY を使って日ごとに集計をする場合、UTC をその人のタイムゾーンの日時に変換してから、GROUP BY する必要が出てきます。東京のように UTC との時差が固定(+9時間)の場合は、その分だけ足し引きして GROUP BY すればいいのですが、サマータイムがある国など時差が変動する場合、単純に足し引きすると、変わり目で時差がずれてしまうことが簡単に起きてしまいます。

 

例えば、2012年のアメリカでは 3月11日の2時にサマータイム(Daylight Saving Time)が始まり、時計が3時に進みました。

UTC太平洋標準時
PST (UTC-8)
太平洋夏時間
PDT (UTC-7)
3月11日 08:00 3月11日 00:00  
09:00 01:00  
10:00 02:00 03:00
11:00   04:00
|   |
3月12日 00:00   17:00
|   |
06:00   23:00
07:00   3月12日 00:00
08:00   01:00

このように、3月11日は実質 23 時間ですので(UTCで 3月11日8時から3月12日7時)、この日だけ 23 時間で GROUP BY するようにしないといけません。こういう場合は、DB 側でもタイムゾーン変換をする必要が出てきます。

 

タイムゾーン変換を行う場合、変換の元になるタイムゾーンの情報が必要になります。tz database と呼ばれる有名なデータベースがあり、多くのシステムはこれを元にタイムゾーン変換を行っています。サマータイムや政治的な理由でどこかの国のタイムゾーン情報が変わるたびに、データベースも更新されていて、年に何回も更新されています。現在は ICANN と IANA が管理していて、FTPのリストを見ると 2011 年は a から n まで 14 回更新されていることがわかります。

本題

それで、ここから本題なんですけど、アプリケーションとデータベースの両方でタイムゾーン正確に扱いたい場合、同一のタイムゾーン情報を参照しないと、変換が一致しないケースがでてきます。

そこで今回は JavaMySQLタイムゾーン変換を合わせる方法の一つを紹介したいと思います。試すには MySQLMaven と Git が必要です。Java では Joda Time というライブラリを使います(最近はデファクト?)。今回はうるう秒は扱いません。今年の7月1日に8時59分60秒が挿入されるというホットな話題なので少し調べてみたのですが、話すと長くなってしまうので気が向いたら別エントリで。Joda Time も未サポートみたいですし。

ビルド

まず tzcode と tzdata を IANA からダウンロードして同じディレクトリに展開します(今回は latest)。

wget ftp://ftp.iana.org/tz/tzcode-latest.tar.gz
wget ftp://ftp.iana.org/tz/tzdata-latest.tar.gz
mkdir tz
tar xvzf tzcode-latest.tar.gz -C tz
tar xvzf tzdata-latest.tar.gz -C tz

mysql_tzinfo_to_sql を使って、タイムゾーンデータのSQLファイルを作成します(参考)。

cd tz
make TOPDIR=.. posix_only
cd ..
mkdir output
mysql_tzinfo_to_sql etc/zoneinfo > output/tzinfo.sql

次に Joda Time (2.1) のタイムゾーン情報を変更してビルドします(参考)。 

git clone git://joda-time.git.sourceforge.net/gitroot/joda-time/joda-time
cd joda-time
git checkout -b v2.1_tz tags/v2.1
cp ../tz/* src/main/java/org/joda/time/tz/src
git clean -f
mvn clean package
mv target/*.jar ../output
# git commit -a -m "update tzdata to latest version"
cd ..

これで output ディレクトリに sql と jar ファイルが出来上がり。tzinfo.sqlmysql データベースに流し込めばタイムゾーンが更新されます。joda-time.jar はクラスパスに入れてあげてください。

以上で JavaMySQLタイムゾーン情報が一致し、時差を正確に扱えるようになりました。

テスト

試しに MySQLタイムゾーン変換できるか試してみましょう。

mysql -uroot mysql < output/tzinfo.sql

次にテーブルを作って、データを挿入。

mysql> CREATE TABLE tz (id int AUTO_INCREMENT PRIMARY KEY, dt DATETIME NOT NULL) ENGINE=InnoDB;
mysql> INSERT INTO tz(dt) VALUES ('2012-03-11 08:00'),('2012-03-11 09:00'),('2012-03-11 10:00'),('2012-03-11 11:00'),('2012-03-11 12:00'),('2012-03-11 13:00'),('2012-03-11 14:00'),('2012-03-11 15:00'),('2012-03-11 16:00'),('2012-03-11 17:00'),('2012-03-11 18:00'),('2012-03-11 19:00'),('2012-03-11 20:00'),('2012-03-11 21:00'),('2012-03-11 22:00'),('2012-03-11 23:00'),('2012-03-12 00:00'),('2012-03-12 01:00'),('2012-03-12 02:00'),('2012-03-12 03:00'),('2012-03-12 04:00'),('2012-03-12 05:00'),('2012-03-12 06:00'),('2012-03-12 07:00'),('2012-03-12 08:00');

CONVERT_TZ を使って、タイムゾーン変換してみると。

mysql> SELECT dt UTC, CONVERT_TZ(dt, 'UTC', 'America/Los_Angeles') LA FROM tz;
+---------------------+---------------------+
| UTC                 | LA                  |
+---------------------+---------------------+
| 2012-03-11 08:00:00 | 2012-03-11 00:00:00 |
| 2012-03-11 09:00:00 | 2012-03-11 01:00:00 |
| 2012-03-11 10:00:00 | 2012-03-11 03:00:00 |
| 2012-03-11 11:00:00 | 2012-03-11 04:00:00 |
| 2012-03-11 12:00:00 | 2012-03-11 05:00:00 |
| 2012-03-11 13:00:00 | 2012-03-11 06:00:00 |
| 2012-03-11 14:00:00 | 2012-03-11 07:00:00 |
| 2012-03-11 15:00:00 | 2012-03-11 08:00:00 |
| 2012-03-11 16:00:00 | 2012-03-11 09:00:00 |
| 2012-03-11 17:00:00 | 2012-03-11 10:00:00 |
| 2012-03-11 18:00:00 | 2012-03-11 11:00:00 |
| 2012-03-11 19:00:00 | 2012-03-11 12:00:00 |
| 2012-03-11 20:00:00 | 2012-03-11 13:00:00 |
| 2012-03-11 21:00:00 | 2012-03-11 14:00:00 |
| 2012-03-11 22:00:00 | 2012-03-11 15:00:00 |
| 2012-03-11 23:00:00 | 2012-03-11 16:00:00 |
| 2012-03-12 00:00:00 | 2012-03-11 17:00:00 |
| 2012-03-12 01:00:00 | 2012-03-11 18:00:00 |
| 2012-03-12 02:00:00 | 2012-03-11 19:00:00 |
| 2012-03-12 03:00:00 | 2012-03-11 20:00:00 |
| 2012-03-12 04:00:00 | 2012-03-11 21:00:00 |
| 2012-03-12 05:00:00 | 2012-03-11 22:00:00 |
| 2012-03-12 06:00:00 | 2012-03-11 23:00:00 |
| 2012-03-12 07:00:00 | 2012-03-12 00:00:00 |
| 2012-03-12 08:00:00 | 2012-03-12 01:00:00 |
+---------------------+---------------------+
24 rows in set (0.00 sec)

ちゃんと変換できましたね!後は GROUP BY でもなんでもやっちゃってください。

ついでに

Google Closure Library を使うと JavaScript でもタイムゾーン変換もできちゃいます。詳しいことは id:teppeis による、時を超えた JavaScript で解説されています。goog.i18n.TimeZone 用のタイムゾーンデータを作る必要が出てきますが、残念ながら公式な作成方法が提供されていません!どうやら pytz から作られているようですが、GWT で使われているデータを参考に 自力で tz database から作らないといけないようです。ただ、Closure では 標準時差 (std_offset) を一つしか設定できず、標準時差の変更に対応していません。。。って細かい話は置いておいて、先ほど作成した Joda Time からの方が少しは楽に生成するかと思います。Joda Time がやっていることを真似すれば JavaScript でも上手くタイムゾーンを扱えるので、興味があればソース読んで勉強してみてください。

最後に

この記事では tz database から JavaMySQL 用のタイムゾーン情報を生成する方法を紹介しました。肝心なことは、タイムゾーン情報は頻繁に変更されるので、タイムゾーン変換する時は、元になったタイムゾーン情報が何かを意識するようになってもらいたいなと思います。

(追記)

とは言っても、普通の使い方で影響が出る範囲はほとんどないと思うので、神経質になる必要はないんじゃないかと思います。

サイボウズを辞めて、Synclogue に転職しました

 

2012年5月31日を持ちましてサイボウズ株式会社を退職しました。

新卒で入社してから4年間、いろいろな人にお世話になりました。本当にありがとうございます。

6月1日から Synclogue (シンクローグ)というベンチャー企業でお世話になります。

 

サイボウズでは、目立った活動はしていないのですが、ここ2年半くらいは kintone(キントーン) というアプリケーションプラットフォームを開発していました。

ドラッグアンドドロップでお手軽にフォームを設計できるのがウリですが、その裏側でレコードを格納するスキーマレスなデータベースを管理する部分をメインに、サーバーサイド全般の開発を担当していました。JavaMySQLは大好きです。

クライアントサイドもいろいろやりましたが、最後に id:ama-chiPhone アプリ用のウェブページを作ったので、アプリストアに登場する日をお楽しみに。

 

サイボウズには刺激を与えてくれる優秀なエンジニアが多く、4年間開発に没頭することができました。自分が感じたサイボウズの良いところを挙げると

  • ウェブアプリ開発に必要な技術を上から下まで(CSSからDBまで)高いレベルで実践できる環境がある
  • インフラ、ミドルウェア、モバイル、パッケージ製品などウェブアプリ以外の開発力もちゃんとある
  • 開発プロセス、チームががっちりしているので、開発のみに集中できる
  • 品質保証がしっかりしていて、レビューや試験に対しても時間を多く使える
  • ラボの凄い人と交流(仕事も)でき、考え方が変わってしまうくらいの刺激になる
  • 勉強会も盛んで、新しい技術のキャッチアップも早い
  • なんだかんだ親切な人が凄く多くて、みんな助けてくれる

こんな感じで、製品の正しい作り方を学び実践してきた手応えはあり、製品開発に関しては自信を持ってできるようになれたんじゃないかなと思います。ここまで成長できたのはサイボウズのおかげです。

 

その反面、いろいろな立場の人が開発に関わるので、自分の判断で行動できる部分が限られます。不具合を直したくても手を出せなかったり、新しい機能をいろいろ試してみるにも工数の調整が必要だったり、やりたいことをやるためにエネルギーを使わないといけないもどかしさはありました。

それでもプログラマという立場で得意なことをやるのは楽しいし、ちゃんと成果も出るので居心地は悪くはなかったのですが、自分のキャリアを考えた時にもっと幅広い経験を積みたいと考えていました。

そんな時に Synclogue という凄い野望のスタートアップに参加する機会を頂くことができました。技術的なハードルは高く挑みがいのあるプロジェクトで、完成したら凄い製品になるのは間違いありません。

職場を変えないと新しいチャレンジができないのは自分の力不足です。Synclogue では、新しい仲間と協力し、本気でぶつかりあって、世の中に役立つ素晴らしい製品を作りたいという気持ちでいっぱいです。

 

最後に、これからも kintone とサイボウズが進化していく姿をすごく楽しみにしています。
今までありがとうございました!これからもよろしくお願いします!

 

 f:id:hikoma:20120525181045j:plain
すばらしい仲間と一緒に働けたことを誇りに思っています。

Javaの暴走スレッドを見つける (2)

前に、コマンドだけで見つけるやり方を書いたのですが、このやり方だと瞬間的なデータしか取得できません。そこで ThreadMXBean にある getThreadCpuTime メソッドを使う方法を試してみました。このメソッドは指定したスレッドの合計 CPU 時間を返してくれるので、CPU 時間を2回取得し、その間の時間で割れば、平均 CPU 使用率を得ることができます。10秒間で95%以上使っているスレッドを検知するみたいな使い方ができそうです。

コードはこんな感じになりました。

process メソッドの中で、前回 process メソッドが呼ばれた時からの CPU 使用率の平均を求めて、threshold 以上だった場合に、handle メソッドを呼び出してくれます。maxDepth は取得するスタックトレースの深さを指定する変数です。

デフォルトでは、このクラスがロードされている JVM のスレッドを監視しますが、JMX で接続すればリモートの JVM にもアタッチできます。Maven Tomcat Plugin などでサクッとテストする場合には MAVEN_OPTS に以下のパラメータを指定すれば JMX を受け付けてくれるようになります。

  • -Dcom.sun.management.jmxremote
  • -Dcom.sun.management.jmxremote.port=<port番号>
  • -Dcom.sun.management.jmxremote.ssl=false
  • -Dcom.sun.management.jmxremote.authenticate=false

自作Mavenプラグインにヘルプを付けよう

Maven 使ってチーム開発していると、ビルドプロセスで独自の処理が必要になって、プラグインを自作する機会がちょいちょいあります。

ただ、自作したプラグインって、ちょっと使っていないと使い方を忘れることがよくあります。公開されているプラグインだったら、サイトを見に行けばいいんですけど、自作の場合は面倒なので準備しないことが多い。

サイトがなくてもコマンドで確認することはできて、例えば、tomcat プラグインだったらこんな感じ。

$ mvn tomcat:help
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'tomcat'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [tomcat:help] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [tomcat:help {execution: default-cli}]
[INFO] org.codehaus.mojo:tomcat-maven-plugin:1.1

Tomcat Maven Plugin
  The Tomcat Maven Plugin provides goals to manipulate WAR projects within the
  Tomcat servlet container.

This plugin has 19 goals:

tomcat:deploy
  Deploy a WAR to Tomcat.

tomcat:deploy-only
  Deploy a WAR to Tomcat witjout forking the package lifecycle

tomcat:exploded
  Deploy an exploded WAR to Tomcat.
…

 でも、これって自作プラグインだと有効になってない場合が多い。

mvn help:describe -Dplugin=プラグイン名 とか長いコマンド打てば自作プラグインでも見れたりするんですけど、このコマンドを覚えるのが面倒。

じゃあ、どうすればいいかと言うと、HelpMojo を作りましょう。ただ、HelpMojo を自分で実装するのはバカバカしいですね(help:describe で見れるのに)。そこで、便利なプラグインがちゃんとあります。

それは Maven Plugin Plugin

使い方は超簡単。自作プラグインの pom.xml にプラグインを追加するだけ。

http://maven.apache.org/plugins/maven-plugin-plugin/examples/generate-help.html

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-plugin-plugin</artifactId>
        <version>2.9</version>
        <executions>
          <execution>
            <id>generated-helpmojo</id>
            <goals>
              <goal>helpmojo</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  ...
  </build>
  ...
</project>

これで、使い方をわからなくなっても、mvn プラグイン名:help で使い方を簡単に確認することができますね。

Javaの暴走スレッドを見つける

簡単な方法がJava Obsessionというブログで紹介されていました。

Figure out why is JAVA eating CPU?

psコマンドで、CPU使用率が高いスレッドを見つけて、jstack(もしくは kill コマンド)でスタックトレースを見つけましょうという話です。

大変わかりやすく説明してくれているのですが、若干手作業が多いので、勢いで bash スクリプトを書いてみました。

CPU使用率が95%以上のスレッドのスタックトレースを出力するスクリプトです。CPU使用率の閾値を変更したい場合は ./java-cpu-monitor.sh 99.9 のようにパラメータで渡せます。

watch コマンドと tee コマンドを組み合わせると便利ですかね?

5秒置きに cpu.log に出力する場合は

watch -n 5 './java-cpu-monitor.sh | tee -a cpu.log'

でよいかと思われます。

 

テキトーなスクリプトなので、好きに使ってください。バグがあったら教えてくれると助かります。自分でも perlpython で書けって思いましたが、スクリプト言語からコマンドを呼び出すのに抵抗があって。。