2008年10月28日火曜日

クロージャー

Java7でクロージャーが取り入れる予定とのことで、クロージャーとは何かを調べてみた。
クロージャー とは、引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決する関数のことである」とあるが、簡単に言うと関数をモジュールとして扱うことのようだ。
 UDS(Forte)での開発をしていた時、IDE上ではメソッドは独立した存在として扱うことができた。たとえば、あるメソッドを1つのクラスから別のクラスへDrag&Dropしたり、コピー・ペーストしたりなどである。ただし、コードの上ではこれを実現することはできず、メソッド(関数)をオブジェクト同様に引数として渡せれば、、と思う場面があったが不可能であった。
 関数型の言語では関数そのものを引数として渡したり、関数を戻り値にとるような「高階関数」という存在があるが、クロージャーはそれを限定的に使用したものということか。Javaで使用できるようになれば現在はAOPやCallBackとして実装している部分がかなりすっきすとしそうな感じがする。ただし、懸念として記事にもなっているが、Cの関数ポインタのように特に初心者にはわかりずらい、つまりコードを追いにく記述になってしまう場合が多いと思われる。

参考:
ついにJavaにもクロージャ? - James Gosling氏らJDK7へ導入提案

親子クラスで同じフィールド定義があると、、、

トランザクション指定を変えてのテスト中、「CommitInterval」を2以上にしても動作に変化がなく、Debuggerで調べてみて発見。
 子クラス定義で親クラスと同じフィールドを宣言していた。こうした場合、実際のInstanceには同名の2つのフィールドが存在することになり、それぞれ別のデータを保有する。実際には呼び出されるコードが親のものか子のものかによってアクセスする対象が変わることになる。
 Javaでは、こうしたフィールドやアトリビュートの重複定義をハイディングといい、アクセスタイプ(private,public など)や型を含めて制限されていない。つまり、ついうっかり子クラスで親と同じフィールドとアクセッサを定義してしまうと、実行時には親クラスのフィールドは初期値のままということになる。もちろんコンパイルエラーも実行時エラーも出ない。
まさに、調査していたコードがそうであった。しかも子クラスで独自に使用する必然性が感じられないため、たんならミスか?と思われる

参考:
Hishidama's Java Memo
Java言語仕様 第3版
Javaの日々

2008年10月27日月曜日

WinXPなどでExploreのドライブ説明文を変更

StartupScriptなどでマウントさせた場合に、勝手にドライブの説明が作成されてしまう。これを変更したかったのだが、やっと方法が分かった。


VBSでnet useでマウントしたドライブレターの変更方法

Exploreのプロセスを作成しておいて、
exp = WScript.CreateObject("Shell.Application");
そのプロパティを変更する。
exp.NameSpace("Y:\").Items().Item().Name = "新しい説明";

ActionScriptからローカルマシンを調べる

HostNameがとりたかったのだが、かなり難しそう。
JavaよりもSandboxが固くてローカルへアクセスは制限を緩めるようなコード署名もないようだ。見つかった方法は、ActionScriptのFSCommand() => JavaScript => WSH の経路でActiveXObjectを駆使してHostの情報を集めるというもの。できそうだが毎回セキュリティのダイアログはいただけない。なんとかできないか調査は続く。

2008年10月24日金曜日

S2JTAがうまく働かない?

S2Batchでのトランザクション設定のテストに入ったが、Rollbackがうまくいかない。Debugログを出してみると、きちんと「トランザクションをロールバックしました」と出力されるし、開始とロールバックの間でINSERTを実施しているように見えるのだが、INSERTが確定してしまっている。Diconでの定義にトリッキーなことをしている影響だろうか?なぞだ、、、

2008年10月23日木曜日

液晶バックライト

 代替に使用できそうなインバータを手に入れて、再度調べてみると、(CCFLも古くて暗いようなのだが)インバータ自体も問題がありそうだと気づいた。手持ちの別のインバータ(1灯式)をつないで見ると、既存のインバータよりも明るく点灯したためだ。
 買ってきたインバータは、低価格なものが2種類あって非常に悩んで購入したのだが、ネットで調べてみると現在と同じコネクターのものが同じような価格で出ていた。交換してもらえるか頼んでみようと思う。それにしても、狭いところに入れることが多い部品だからか、電源供給側のコネクターはいろんな種類があって各社まちまち。CCFL側は数種類だが違いがある。4灯式の場合は2つを直列にするものが多いが、高級品は並列接続である。
 現在分かっている電源側のピンの概要を記しておく。
  VCC 12V程度が多いようだ:アナログ回路なので電圧の許容は15%くらいありそう
GND: 大電流が必要な場合はVCCとペアで数本をパラにしている
ENABLE: 点灯と消灯の制御用:これは、正論理負論理、3.3V/5V などまちまち
BLT:明るさ調節:ENABLE同様に各種方式がありそうで、単なる潮流電圧だけでなく、パルス変調もある
(PWM:方形波のDuty比率で明度を調節する方式らしい)

2008年10月21日火曜日

H2databaseでErrCode=50200

ロックをかけたトランザクションとは別のトランザクションが同じリソースのロックを取得に行った時に絶対に受け取ることができない組み合わせの場合に発生するようだ。(DeadLockのときもでるらしい)

S2で「RequiresNewTx」を指定したメソッドから特定のデータをInsertし、別の「RequiresNewTx」となるメソッドを呼び出して、その中で同じレコードのUpdateをしていることが原因だったようだ。再現テストしても発生しないため、どうもデバッガでデータを適当に書き換えた結果として発生していたようだ。


参考:http://www.h2database.com/javadoc/org/h2/constant/ErrorCode.html#c50200

LOCK_TIMEOUT_1 = 50200
The error with code 50200 is thrown when another connection locked an object longer than the lock timeout set for this connection, or when a deadlock occurred. Example:

参考2:http://lumber-mill.co.jp/gallery/view/tips/java/h2
ここは、SQLでのExport方法も載せてあった。

$ java -cp h2.jar org.h2.tools.Script -url jdbc:h2:foo -user sa

$ java -cp h2.jar org.h2.tools.RunScript -url jdbc:h2:foo -user sa

トレーニングの本質

トレーニングとは、「一定の基礎的な学習を反復練習しながら身に着けていくこと」(http://ja.wikipedia.org/wiki/トレーニング) であり、教育の1方法である。

教育は様々に定義されてきたが、その定義の仕方は大きく次の4種類に分けることができる。
 語源・語義からの定義 (例 「教育とは、能力を引き出すことを意味する」)
 目標・目的からの定義 (例 「教育とは、よりよく生きるためのものである」)
 方法・手段からの定義 (例 「教育とは、強制の一種である」)
 機能・効果からの定義 (例 「教育とは、社会の再生産である」)

 ここでは、「教育とは人の持つ諸能力が引き出されるよう導くことである」とする定義を採用して論議を進める。

 ほとんどの人には現時点において容易にまたは全く行うことが出来ない事柄がある。しかし、それを偶然ではない何らかの方法によって、行いうる事柄に変えることができたとする。この方法の適用や伝達が他者によってなされた場合に狭義の教育を受けたとみなすことが出来る。つまり、その他者によって能力が引き出されるように導きを受けたといえる。一方、自分自身での試行錯誤や文献などの資料から能力を高めた場合は、自己学習をした言える。
 ここで、「導き」に含まれるさまざまな意味の中から、現在の地点からある別の地点への物理的な移動を助けることに限定して考えてみる。すると、導くとは方向や距離、着地する足の高低や地面の柔らなさなどを示して、導きを受ける側の者が自らの力で当該地点にたどり着けるように援助をすることと捕らえることができる。もちろん、すでに持っている能力に応じて援助の範囲は変化することとなる。
 たとえば、目が全く見えない者に対しての導きは詳細なものになるべきであり、自分で再度同じ道を進むことが出来るようにするためには、視覚以外の方法で印となるものを用意する必要がある。逆に、当該箇所をよく見知っている者に対する導きは、「XXの交番から右へ15メートル」などのようにポイントとなるものを示すだけで十分となる。
 また、導きを与える側の物は導く事柄に対して充分な能力を持っている必要がある。そうでないと、盲人を手引きする盲人の喩えのようの状態に陥ってしまうであろう。

■まとめ
 トレーニングとは教育の一種であり、目的とする能力を獲得するために、
                        基礎となる事柄を反復練習しながら身につけていくこと

 トレーニングを施す人は、当該能力を充分に備えている必要がある

液晶の修理

前にもらっていたバックライトがすぐ消える液晶の修理を再開。
インバータを別のものにするときれいに点灯するし、時々うまく表示される場合もあるため、蛍光管(CCFL)は正常と判断した。インバータも正常かもしれないがよくわからず。電圧を測るとどうも直流ではなくPWM方式でDuty比率で輝度を変化させている模様。とりあえず、Enableらしき端子の電圧が、正常時は1.8V 程度で、異常時は0.5Vとか3.2Vであることがわかった。

2008年10月17日金曜日

GoogleChromeが中途半端インストール

インストールして起動しようとしたが、インストーラが途中で吹っ飛んだ感じ。ファイルも存在し、ショートカットやメニューなどもできている。話題になっている、GoogleUpdate.exeも動作しているのに、初期軌道のダイアログが一瞬で消えてしまう。
ネットで調べると、起動時のオプションとして以下の2つがいいらしいので、追加。
-no-sandbox -start-single
結果としてはこれでは解決せず。ちなみに使っているのはMcAfeeのウイルス防御。
ショートカットのプロパティから互換性タブを開いてWin2000モードでの起動を試みる
がまったく動作せず。試しに、
 □詳細なテキストサービスを無効にする
をチェックしてみると、普通に起動した。何なんだろう??

Runtime.getRuntime().exec()でエラーが、、、

Tomcatでテストしているときは発生しなかったRumtime#exec()のエラー
  IOException ... CreateProcess ... error=2
というもので、Googleして、太郎日記 から分かったのは対象のファイルがパスに入っていないと発生するらしい。カレントを移動してから実行させているのだがそれだではだめらしい。

 ちなみに、対象はCMDファイルですので、以下のように起動させることにして一件落着。

cmd.exe /Q /C xxx.cmd p1 p2

通常のWin32環境で cmd.exe がパスに入っていないことはあり得ないので、これでOKのはず。

2008年10月16日木曜日

S2Daoでの複数パラメータUpdate

規約上できないのね、、、

・DaoのInterfaceは次のようなもの、
int update(SomeEntity entity, Integer version);

・SQLはファイルで、以下のような感じ。
Update xxTable set version = /*version*/ where version = /*entity.version*/123

んで、実行すると以下のようにHashMapの操作中にNPE。

java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:157)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:730)
at org.seasar.framework.beans.factory.BeanDescFactory.getBeanDesc(BeanDescFactory.java:55)
at org.seasar.dao.node.BindVariableNode.accept(BindVariableNode.java:54)
at org.seasar.dao.node.ContainerNode.accept(ContainerNode.java:34)
at org.seasar.dao.impl.AbstractDynamicCommand.apply(AbstractDynamicCommand.java:66)
at org.seasar.dao.impl.UpdateDynamicCommand.execute(UpdateDynamicCommand.java:39)
at org.seasar.dao.interceptors.S2DaoInterceptor.invoke(S2DaoInterceptor.java:53)
at org.seasar.dao.pager.PagerS2DaoInterceptorWrapper.invoke(PagerS2DaoInterceptorWrapper.java:71)
at org.seasar.springframework.batch.dao.BatchStepExecutionDao$$EnhancedByS2AOP$$14eaec9$$MethodInvocation$$update5.proceed(MethodInvocationClassGenerator.java)

 調べてみるとS2Daoではメソッドのパラメータ名が分からないので、2つあるパラメータから適切なものを取得できずにエラーとなっている模様。
 では、@Argsを付けるとうまくいくのかは明日に回そう。

2008年10月15日水曜日

睡眠における対称性の破れ

睡眠の研究によると、人は眠っている間に「ノンレム睡眠」と「レム睡眠」を繰り返している。ちょうど、「体」と「頭」を時間差で休ませているようだ。この2種類の睡眠は約90分で1周期であるという。だからこの90分の倍数で睡眠をとるといいとのことである。
 しかし、自分の経験からすると、1周期の90分は同質ではない場合がありそうだ。90分で眠りが浅くなり、覚醒しやすくなる場合と、90分では全く覚醒せず、180分たってやっと覚醒しやすくなる場合がある。つまり、こんな感じ。
 1.周期1 ・・・ 90分
 2.覚醒しやすいインターバル ・・・ ??分
 3.周期2 ・・・ 90分
 4.覚醒しにくいインターバル ・・・ ??分
 5.周期3 ・・・ 90分
 6.覚醒しやすいインターバル ・・・ ??分

2008年10月14日火曜日

Tomcat5と6のはざまで

Tomcat5で動作しているWebApp(S2, teeda)をTomcat6にて起動しようとしていたら、、、
commons-el がないから起動できないとのエラーログ。POMを見てみると、見事にExcludeしてあった。

<dependency>
<groupId>org.seasar.teeda</groupId>
<artifactId>teeda-tiger</artifactId>
<version>1.0.12</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.seasar.container</groupId>
<artifactId>s2-extension</artifactId>
</exclusion>
<exclusion>
<groupId>org.seasar.container</groupId>
<artifactId>s2-framework</artifactId>
</exclusion>
<exclusion>
<groupId>commons-el</groupId>
<artifactId>commons-el</artifactId>
</exclusion>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>

調べてみると、Tomca6では「Unified EL」を使用するように仕様が変わった(JSP/Servletの仕様に連動していの変更)ため、commons-elは不要になったようで、クラスパスには存在しなくなったために上記のエラーとなっていた。

[[教訓]]他で動作していて自分のところでエラーとなる場合は環境を疑うこと

大阪王将のバイキング

オーダーバイキングなので、席で注文して作りたてを食べられるのがいい。ちょっと待つこともあるが、他のバイキングに比べると満足度が高いと思う。2回目の夕食も「あさパス」を利用して一人500円安くなった。
 よく間違ってしまうが、餃子の王将とはまったく違う店で、ある意味対極(ちょっと高い、時間かかる、うまい)

ServletのinitからContextPathを取得することは、

無理のようです。 いろいろ調べたりやったりしてみましたが、、、
実際には、LocalHostやLocalPortと共にContextPathも知りたがったのだが、Initで与えられたパラメータは、ServletConfigだけなので、そこから取得できるServletContextまでは分かっても、そのcontextのパスは調べようがないようだ。これがdoGetなどのServletRequestを与えられるメソッドなら、問題なくすべて求められるのだが、、、、残念。
ServietのinitからTimerTaskで自分のマシンからブラウザを開いて特定のページを表示させたかったのだが、やむなく断念し、別のページから当該パスなどを登録するように変更した。

2008年10月11日土曜日

RemoteWeb

さて、リモートウェブのほうだが、昨夜はダラダラと朝方まで作業してしまった。
はまっていたのは、MylinとTracの連携部分。ついでとばかりにTracOnSolaris
のPluginとして「AccountManager」を追加したのだが、Tracが起動しなくなるは、
認証が無効になるわで散々なことに。結局、以下のページの助けを借りて何とか復旧
して少し作業、、、って朝になってる。

蝸牛の宿(別館)
mahataの日記

Mylinの解説は、@ITさん。
Mylyn&Tracでリズムに乗ってタスクを大掃除♪

2008年10月10日金曜日

S2TestCaseでの初期化処理など

 通常のTestCaseであれば、setUp() tearDown() などのメソッドをOverRideすることで初期化および終了処理をかけるのだが、S2の場合はAutoBindingによりフィールドに値がセットされるタイミングが問題となる。setUp() の中でフィールドにDIされていることを期待した処理を書くと、NPEで落ちることになる。
 そこで、S2TestCaseの動作を調べてみると、以下のような順序でS2TestCaseは処理を進めていく。(org.seasar.framework.unit.S2FrameworkTestCase#runBare() より抜粋)

setUpContainer();
setUp();
setUpForEachTestMethod();
container.init();
setUpAfterContainerInit();
bindFields();
setUpAfterBindFields();
doRunTest();
tearDownBeforeUnbindFields();
unbindFields();
tearDownBeforeContainerDestroy();
container.destroy();
tearDownForEachTestMethod();
tearDown();
tearDownContainer();

つまり、フィールドにAutoBindingでDIされた後で初期処理を入れたい場合は、setUpAfterBindFields() をOverRideするといいということだ。

S2Dao ではまる

S2Daoで、Selectのパラメータに中途半端にMapが使えるため、はまってしまった。
問題となったDAOの定義は以下のようなもの(Interface, Foo はEntity)

Foo selectById(Object id);

使っている側はこれ、(key はHashMapで、"id":"1" のEntryあり)

Foo = fooDao.selectById((Map)key);

んで、出たエラーの概要がこれ、


org.seasar.framework.beans.IllegalPropertyRuntimeException:
[ESSR0059]クラス(org.seasar.springframework.batch.item.sample.Foo)のプロパティ(id)の設定に失敗しました。理由はjava.lang.IllegalArgumentException: object is not an instance of declaring class


うーーーむ、どうもObjectで指定するとEntityと同じTypeのオブジェクトが来たと思って処理するようで、Mapは考慮されていない。念のためにアノテーションを追加して以下のようにしてみると、

@Query("id = ?")
Foo selectById(Object q);

無理やりIDのカラムにあてはめようとしてエラーになっている模様。(@Arguments("id")も試したが結果は同じ)


org.seasar.framework.exception.SQLRuntimeException:
.....
Caused by: org.seasar.framework.exception.SSQLException:
[ESSR0072]SQLで例外(SQL=[SELECT T_FOOS.name, T_FOOS.value, T_FOOS.id FROM T_FOOS WHERE id = ?], Message=[17004], ErrorCode=null, SQLState={3})が発生しました
.....
Caused by: java.sql.SQLException: 列の型が無効です。


うーーーむ、どうやらMapからIDを拾ってはくれないようだ。S2Daoの仕様によると、argumentの型はPrimitiveかwrapperが基本で、DTOも使えるとのことで、Mapの記述はなし。S2JdbcがMapでQueryパラメータを指定できるので、同じようにできないかと思ったがやっぱり断絶があった模様。(もしかすると、最新のS2Daoならできるかも、、、、現在はS2Dao-1.0.47)

 続いて、最初からMapで指定したらどうなるか?

Foo selectById(Map q);

なんと!!! ちゃんととれてる。やればできるじゃないかS2DAOと思ったのも束の間、Mapとして与えるプロパティがどう変わっても取得できるものが同じでることが判明。つまり、

"id":"1" ==> Foo(id=1,...)
"id":"2" ==> Foo(id=1,...)

うーーん、これじゃ使えない、、、、試しに、@Arguments("id")としてみると。やっぱり「列の型が無効」とのこと。


Caused by: java.sql.SQLException: 列の型が無効です。


やっぱり、Mapはだめだ。

S2Jdbc と S2DAO の混在

混在環境での問題点など。
1)Entityのアノテーションが供用できない
S2Jdbc: @Entity @Table(name = "Table")
S2Dao: @Bean(table = "Table")

S2Jdbcでは、Entityを使わない方式もあるので、SQL文でTable名を与えてしまえばEntityは不要なのだが、、、ついつい同じEntityだしと思って使い始めると????な状況になることがあった。

2008年10月9日木曜日

S2Jdbcのテストではまる

S2JdbcをS2TestCaseを継承したクラスで、JUnit4にてテストしていたら、「oracleDialect」 のコンポーネントが見つからず、jdbcManager が生成できないエラーとなった。

あちこち調べたが有意な情報が見つからず、以下のを参考に oracleDialect を定義した。

<!-- need for S2Jdbc http://d.hatena.ne.jp/GARAPON/20071119 -->
<component class="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>
<component name="oracleDialect"
class="org.seasar.extension.jdbc.dialect.OracleDialect" >
</component>


一応動いたが、なんか釈然としない。ほぼ同じ構成でhsqlDialectを使用するテストは何の問題もないのに、、、

2008年10月8日水曜日

タグをそのまま表示

POMのソースを貼り付けてあとから見たら、タグが吹っ飛んでいた。
少々調べると、
 <PRE>はスペースや改行はそのままだが、タグはだめ。
 <PLAINTEXT>は、すべて出してくれるが、
  Bolggerが追加した<BR />まで表示されてしまうことと、
  終了タグがないので、文末にしか使用できないことで却下

結局変換した・・・残念!
参考:お世話になったタグ変換ツール
 蓄々HTML実体参照変換
 タグ無効化変換

Maven2-surefire:test でエラー

JUnitが順調に「オールグリーン」となり、MavenにMakeさせてみたらところ、
見事に BUILD FAILURE となってしまった。調べてみると
Testで使用するEntity(単なるJavaBean的クラス)をTestしようとして起こって
いるようだ。Testメソッドが1つもないのだからそりゃ駄目だわな、、、
ということで、surefire プラグインの仕様を確認して以下の設定をpomに
追加、 (Testで始まるクラスを除外する)
-----------------------------------------------------------

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<excludes>
<exclude>**/Test*.java</exclude>
</excludes>
</configuration>
</plugin>

-----------------------------------------------------------
ところが、これでMavenするとTestが1件もなしになってしまう!
よく見ると、Testクラスの名称が XxxTests.java となっているでは
ないか~~~~~! ということで、以下のを追加して解決
-----------------------------------------------------------

<includes>
<include>**/*Tests.java</include>
</includes>

-----------------------------------------------------------
今日はここまで。
S2Batch JUnit 続き
 昨日の無限ループだが、原因はAOPのPointCutの指定にあった。
RepeatOperationsInterceptorをAOPするテストなのだが、その仕様を理解しないまま対象メソッドを「.*」としていた。
今回のInterceptorの仕様としては、
* メソッドのリターンがない場合(Voidメソッド)なら無限に繰り返し
* リターンがある場合は、NULLまたはFALSEになるまで繰り返すと
というもので、処理の途中でVoidのSetterを呼んでいる部分が無限ループとなっていた。
対象を絞り込んだところ正常終了となった。

[[教訓]] 仕様が不明な場合は異常となる可能性が低くなる方向から試行するべし。

2008年10月7日火曜日

S2Batch JUnit

SpringBatchをS2に移植している。テストも移植しているが、現在は以下のメソッドで
Testが終了しない。
RepeatOperationsInterceptorTests#testCompleteOnFirstInvocation()

TaskManagerを見ると、2つのjavaw.exe がCPUをほぼ100%占有していた。
調査は明日以降に持ち越し、、、

動的AOPをJUNITしたらエラー

JunitTestの最中にjava.lang.IllegalAccessErro
が発生。メッセージはAop(動的拡張)されたクラスと元のクラスの関係のようだ。
class Xxxx$$Enhance...$$ cannot access its superclass Xxxx
--- しばらく調査:
//http://tech.groups.yahoo.com/group/junit/message/6508
によれば、このエラーは、アクセスできないフィールドやメソッドを修正したり呼び出したりした場合に発生し、その原因としては実行時にクラス定義が互換性をなくすように変更されていた場合となっている、とのことだ。
public な Consutructorがないのが原因かなと思って入れてみたりしたがだめ。ほぼ同じ構成のテストが動作しているので比較してみると、Privateな要素に問題があるようだ。
結局、問題は以下の点だった。
* AOPの対象となるクラスが、Testクラスの内部Privateクラスであった
* AOP系のロジックはTestクラスにて書いていた
よって、コンパイルまでは問題ないのだが、実行してみるとAOPで作成されたクラスは、Privateな内部クラスの子供であるため、親クラスとしては参照できなくなり上記のエラーが発生してしまった。

[[ 教訓 ]]
cannot access => Scopeが何か(public, protected, package, private)に注目すること!

iPhone関連:
iPhone開発で使用するCocoaはObjective-Cであり、Java/Perl/Python/Rubyなどとブリッジ可能

ついでにメモ:
S2TestCase でトランザクションテスト:
setup() で、include("j2ee.dicon")をしておいて、テストメソッド名の最後にTxをつける
参考(http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/seasar/s2-struts/doc/S2Unit.html?rev=1.1)