JUnitタスクを並列実行する方法
Antで複数のJUnitテストを並列に実行する方法です。実行時間の短縮が期待できます。
実装には以下の記事を参考にしました。
solutions daily: Making JUnit tests run parallely
標準の記述
Antで複数のJUnitテストを実行したい場合、普通に書くと以下のようなbuild.xmlになると思います。
<target name="execute.test"> <junit fork="true" printsummary="true"> <classpath> <path refid="${test.classes}" /> </classpath> <formatter type="xml" /> <batchtest todir="${test.reports}"> <fileset dir="${test.sources}"> <include name="**/*.java"/> </fileset> </batchtest> </junit> </target>
${test.sources}配下の全テストクラスを実行するターゲットです.
これを複数スレッドで並列に実行できるように書き換えます。
手順
1. ant-contrib(Antの拡張ライブラリ)のjarをダウンロードし、Antのクラスパスに追加します。
2. ant-contribのタスクを有効にするため、以下の内容をbuild.xmlに追加します。
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
3. execute.testターゲットを、テストクラスを1つだけ実行するように修正します。
<target name="execute.test"> <pathconvert property="test.source.relative"> <fileset file="${test.source.absolute}" /> <map from="${test.sources}/" to="" /> </pathconvert> <junit fork="true" printsummary="true"> <classpath> <path refid="${test.classes}" /> </classpath> <formatter type="xml" /> <batchtest todir="${test.reports}"> <fileset dir="${test.sources}"> <filename name="${test.source.relative}" /> </fileset> </batchtest> </junit> </target>
4. ant-contribのforeachタスクを使用し、上記3のexecute.testを呼び出します(イメージとしては、foreachタスクがfor文で、そのループの中でexecute.testメソッドを呼び出している、という感じでしょうか)。このforeachタスクのparallel属性をtrueにすることで、それぞれのexecute.testがマルチスレッドで実行されます。また、このときの最大スレッド数をmaxThreads属性で制御できます。
<target name="execute.tests.parallel"> <foreach target="execute.test" maxThreads="5" inheritall="true" inheritrefs="true" parallel="true" param="test.source.absolute"> <path> <fileset dir="${test.sources}"> <include name="**/*.java"/> </fileset> </path> </foreach> </target>
以上
参考書籍:
- 作者: Steve Holzner,長瀬嘉秀(監訳),株式会社テクノロジックアート
- 出版社/メーカー: オライリージャパン
- 発売日: 2005/11/18
- メディア: 大型本
- 購入: 2人 クリック: 20回
- この商品を含むブログ (19件) を見る
あるディレクトリ以下の.classファイルを再帰的にJadるAntタスク
突然ですが、jadってご存知ですか?javaファイルをコンパイルしてできた.classファイルを、元のjavaファイルに戻すためのいわゆる「デコンパイル」のツールです。
今回、jdbcドライバの中身を見たくて、解凍したJarに含まれている.classファイルを一度でデコンパイルしたかったので、Javaの練習を兼ねてAntのタスクにすることにしました。せっかく作ったのでここでさらしておこうと思います。
Antについてはこの辺↓を見ていただくとして、
http://www.techscore.com/tech/Java/ApacheJakarta/Ant/1/
今回作るタスクの、build.xmlでの記述方法はこんな感じです。
<?xml version="1.0" encoding="UTF-8"?> <project basedir="." default="jad"> <property name="classes.dir" value="classファイルのルート" /> <target name="jad"> <jad basedir="${classes.dir}" recurse="true" executable=""> <arg value="-lnc" /> <arg value="-p" /> <arg value="-s java" /> </jad> </target> <!-- taskdefタグで、独自タスクを読み込みます --> <taskdef name="jad" classname="ant.jad.JadTask" classpath="./ant-jad.jar"/> </project>
jadタスクについて簡単に説明すると、
- basedirで.classファイルのルートディレクトリを指定
- recurseでディレクトリを再帰的に走査するかを指定(true/false)
- executableでjad.exeへのパスを指定
- 子要素のargでは、実行時オプションを指定
といった具合です。
独自タスクを作るには,Taskクラスを継承したクラスを作り、executeメソッドを実装するだけでOK!
そのタスクの本体がこちらです。
/** * あるディレクトリをベースに、再帰的にjadるためのタスク * @author tetran * */ public class JadTask extends Task { private static final String TARGET_EXTENSION = ".class"; private String executable; private String basedir; private RecurseAttr recurse; private List<Parameter> args = new ArrayList<Parameter>(); private File dir; private boolean isRecursive; private String[] executableArray; @Override public void execute() throws BuildException { validate(); isRecursive = Boolean.valueOf(recurse.getValue()); System.out.println(isRecursive); setupTemplate(); try { exec(dir); } catch (IOException e) { e.printStackTrace(); throw new BuildException("File Access Error!"); } } private void setupTemplate() { executableArray = new String[args.size() + 2]; executableArray[0] = isEmpty(executable) ? "jad" : executable; System.arraycopy(argsAsArray(), 0, executableArray, 1, args.size()); } private void exec(File dir) throws IOException { File[] files = dir.listFiles(dirAndClasses()); Runtime runtime = Runtime.getRuntime(); for (File f : files) { if (f.isDirectory() && isRecursive) { exec(f); continue; } String thisPath = f.getAbsolutePath(); log("processing-> " + thisPath); // 対象ファイル名は配列の最後 executableArray[executableArray.length - 1] = thisPath; runtime.exec(executableArray, null, dir); } runtime.gc(); } private String[] argsAsArray() { String[] result = new String[args.size()]; for (int i = 0; i < result.length; i++) { result[i] = args.get(i).getValue(); } return result; } /** * ディレクトリとclassファイルを抽出する。 * @return */ private static FilenameFilter dirAndClasses() { return new FilenameFilter() { @Override public boolean accept(File dir, String name) { if (new File(dir, name).isDirectory()) { return true; } return name.endsWith(TARGET_EXTENSION); } }; } private void validate() { if (basedir == null || basedir.isEmpty()) { throw new BuildException("'basedir' must be designated!"); } dir = new File(basedir); if (dir.isDirectory() == false) { throw new BuildException("such a directory does not exist"); } } // 属性はsetterメソッドで追加する public void setExecutable(String executable) { this.executable = executable; } public void setBasedir(String dir) { this.basedir = dir; } public void setRecurse(RecurseAttr recurse) { this.recurse = recurse; } // 要素の追加はaddXXX(Parameter p)を使う public void addArg(Parameter arg) { this.args.add(arg); } // EnumeratedAttributeを拡張したクラスを用意することで、 // 入力値を制限できる & EclipseのAntエディタで補完される! public static class RecurseAttr extends EnumeratedAttribute { @Override public String[] getValues() { return new String[] {"true", "false",}; } } private static boolean isEmpty (String val) { return val == null || val.isEmpty(); } }
後はこのクラスをjarに固めて出来上がり!
独自タスクを作るときに大事なポイントとしては、
- Taskを拡張したクラスを作る
- executeメソッドを実装する
- 属性はsetterメソッドで追加する
- 子要素はaddXXXメソッドで追加する
くらいを押さえておけば十分だと思います。
ライブラリの拡張って、ちょっと敷居が高いような気がしていましたが、やってみると以外といけるものですね!こういう「自前ライブラリ」をどんどん増やしていきたいと思いました。
ていうか、前回の投稿からもう1年経とうとしていたとは。今後は週一くらいでネタを投下したいです。
OOP中毒?
最近、仕事でのコーディングがなかなか進まない。
原因はいくらか考えられるけど(実力不足とか)、その中の1つとして
「スタイルにこだわりすぎる」ってのがあるように思う。
例えば、変数名に異常なほどこだわったり、パターンを使いたがったり、
一言で言えば「かっこよく」書きたがっているってことかな。
オブジェクト指向本の影響を悪い方向に受けてしまっているようだ。
(まあ、これも実力不足に起因しているとも言えるけど)
なによりもまず「動くコード」を書くことが最優先であるはずなのに、
最初からきれいに書こうとしすぎている。
で、結局たいした進捗もないまま1日が終わってたりすることが多い。
まさに「できないやつ」の典型のようだ。
てなわけで、しばらくはスタイルは気にせず(最低限の規約は守るけど)、
とにかくまずは動くコードを書くようにしていかなければ、と思う次第であります(仕事だから当然か)。
そうやって経験値を積んでいった上で、改めてスタイルを確立できていければいいかなーっと。
きっとその方が楽しいと思うしw
Eclipseのプロジェクト名
今日、JAVA Puzzlar を購入したので実験してみようと思い、
macでEclipse(3.6)を使ってJavaプロジェクトを作成しました。
ところが...
パズル1のisOddを書いてみて実行しようとしたところ、
こんなかんじ↓のエラーが発生して実行できない!?
Exception occurred executing command line.
Cannot run program
"/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java"
(in directory "/Users/xxx/workspace/ぷろじぇくと"): error=2, No such file or directory
どうやら、今回作成したプロジェクトの名前が日本語になっていることが原因みたい。
(いつもは英数字のみなんだけど、今日はたまたま日本語使ってました)
英数字のみの名前に変更しもう一度試してみたところ無事実行できて一安心( ̄。 ̄)
ちなみにWindowsでは日本語名でも問題ないようす。
macでだけ発生するのかも(Linuxは未確認)
これの解決に2時間も費やしてしまったのがたまらなく悲しい...orz
- 作者: ジョシュア・ブロック,ニール・ガフター,柴田芳樹
- 出版社/メーカー: ピアソン・エデュケーション
- 発売日: 2005/11/14
- メディア: 大型本
- 購入: 3人 クリック: 92回
- この商品を含むブログ (56件) を見る
積んどくリスト
いま家にある未読の本をここで整理しておきます。
少しでも興味が出るとよく考えもせずに買ってしまうものだから
ぜんぜん消化が追いつかないw
以下、積んどくリスト @2010/7/11
- 作者: テッド・ハスティッド
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2003/12/10
- メディア: 単行本
- 購入: 1人 クリック: 24回
- この商品を含むブログ (28件) を見る
デコンパイリングJava ―逆解析技術とコードの難読化 (Art Of Reversing)
- 作者: Godfrey Nolan,松田晃一,小沼千絵,湯浅龍太
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/06/03
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 204回
- この商品を含むブログ (20件) を見る
- 作者: エリックガンマ,ケントベック,Erich Gamma,Kent Beck,小林健一郎
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/12/22
- メディア: 単行本
- 購入: 2人 クリック: 29回
- この商品を含むブログ (36件) を見る
- 作者: 沖林正紀
- 出版社/メーカー: 技術評論社
- 発売日: 2008/06/19
- メディア: 大型本
- 購入: 14人 クリック: 247回
- この商品を含むブログ (42件) を見る
- 作者: Alex Martelli,Anna Martelli Ravenscroft,David Ascher,鴨澤眞夫,當山仁健,吉田聡,吉宗貞紀
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2007/06/26
- メディア: 大型本
- 購入: 11人 クリック: 423回
- この商品を含むブログ (85件) を見る
リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing)
- 作者: Justin Seitz,安藤慶一
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/05/22
- メディア: 単行本(ソフトカバー)
- 購入: 4人 クリック: 359回
- この商品を含むブログ (29件) を見る
- 作者: George T. Heineman,Gary Pollice,Stanley Selkow,黒川利明,黒川洋
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/04/26
- メディア: 単行本(ソフトカバー)
- 購入: 11人 クリック: 656回
- この商品を含むブログ (72件) を見る
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)
- 作者: 矢野啓介
- 出版社/メーカー: 技術評論社
- 発売日: 2010/02/18
- メディア: 単行本(ソフトカバー)
- 購入: 34人 クリック: 578回
- この商品を含むブログ (129件) を見る
デザイニング・インターフェース ―パターンによる実践的インタラクションデザイン
- 作者: Jenifer Tidwell,ソシオメディア株式会社,浅野紀予
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2007/01/23
- メディア: 大型本
- 購入: 29人 クリック: 650回
- この商品を含むブログ (89件) を見る
ユーザビリティエンジニアリング原論―ユーザーのためのインタフェースデザイン (情報デザインシリーズ)
- 作者: ヤコブニールセン,Jakob Nielsen,篠原稔和,三好かおる
- 出版社/メーカー: 東京電機大学出版局
- 発売日: 2002/07/01
- メディア: 単行本
- 購入: 14人 クリック: 171回
- この商品を含むブログ (20件) を見る
- 作者: 田中ナルミ,阿部忠光
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2010/02/20
- メディア: 単行本
- 購入: 1人 クリック: 102回
- この商品を含むブログ (12件) を見る
- 作者: 林晴比古
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/07
- メディア: 単行本(ソフトカバー)
- 購入: 19人 クリック: 182回
- この商品を含むブログ (41件) を見る
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2008/11/22
- メディア: 単行本
- 購入: 46人 クリック: 720回
- この商品を含むブログ (82件) を見る
- 作者: John Viega,葛野弘樹(監訳),夏目大
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/04/26
- メディア: 単行本(ソフトカバー)
- クリック: 123回
- この商品を含むブログ (22件) を見る
- 作者: 長谷川高
- 出版社/メーカー: WAVE出版
- 発売日: 2008/02/18
- メディア: 単行本(ソフトカバー)
- 購入: 33人 クリック: 455回
- この商品を含むブログ (36件) を見る
- 作者: マイケル・ブルックス,楡井浩一
- 出版社/メーカー: 草思社
- 発売日: 2010/04/22
- メディア: 単行本
- 購入: 8人 クリック: 272回
- この商品を含むブログ (41件) を見る
数学ガール/フェルマーの最終定理 (数学ガールシリーズ 2)
- 作者: 結城浩
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2008/07/30
- メディア: 単行本
- 購入: 35人 クリック: 441回
- この商品を含むブログ (259件) を見る
これ以上積み上げてしまわないためにも、
週に2冊くらいのペースは維持していきたいなー
iPhone4ゲットだぜ!
ついに!ねんがんのiPhone4をてにいれたぞ!(AA略)
てゆうか、受け取れるの来週末だと思ってたから
装備品(保護フィルムとか)全然用意してなかったよw
ハダカのまま使うのはいやなので、
とりあえず適当な保護フィルムを買ってくることに。
ちなみに買ったのはこれ↓
iBUFFALO iPhone4S/iPhone4用 液晶保護フィルム 超スムースタッチ BSIPP1FT
- 出版社/メーカー: バッファローコクヨサプライ
- 発売日: 2010/06/26
- メディア: エレクトロニクス
- 購入: 4人 クリック: 30回
- この商品を含むブログ (3件) を見る
んで、使い始める前の初期設定を開始する。
回線の切り替えとか、
アドレス帳の移行とか、
メールアドレス変更のお知らせとか、
いろいろめんどい作業を終わらせ、
さていろいろ試そうか、と思ったら!
...日曜日終了のお知らせですよ(´Д`)
いいさ。手に持ってるだけで幸せな気分になるし。
いろいろやるのは明日からの楽しみにとっておくさ( ̄ー ̄)
それにしても、久々にいい買い物をしたなぁ。
一括払いにしたから来月の支払いが少し怖いけど。
明日からが楽しみだなー
使い倒すぞー!
そろそろ何か書こう
開設したはいいものの、何を書いたらいいか
わからずにずっと放置してた。
でもこのままだと永遠に書き始めない気がするので
適当に何か書いていこうと思う。
主にプログラミング関連の技術メモとして使おうと
思ってはいるけど、ほかにも思いついたこととか
書いてみよう。
とりあえず目標は週一回更新!
ってことで、よろしくおねがいします。