T2連携をしてグラフ表示

ちょっとだけ凝ったアプリケーションを作成してみました。
内容としてはアプリケーションサーバGlassFish)の上にT2でウェブアプリを作成し、AMF通信にてデータを取得、JavaFXでグラフ描画という流れです。ソースコードは、こちらより参照のこと。見るだけならばTracをどうぞ。

尚、サーバに設置しているんですが、どうもAMF周りでエラーが発生しているようですorzアクセス権関係のようですが・・・。
ローカルにプロジェクトを作って実行すれば問題ないので、チェックアウトして試してみてください。

T2とAMF通信

まずT2ですが、MVCにおけるCの部分、つまりHTTPリクエストを受けて事前処理をごにょごにょして、ロジックをキックしてという所と、ロジックの結果からHTTPレスポンスを返す部分に特化したフレームワークです。Springやその他のフレームワークにも当然ながら含まれている機能ですが、DIコンテナやViewのテンプレートエンジン、O/Rマッパなどに依存しない所が特徴です。
また、Flexと連携するために用意されているAMF通信の機能がデフォルトで組み込まれており、JavaからAMFの形式(バイナリ)にする事ができるわけです。逆に言えばAMFからJavaへの変換も可能なわけで、JavaFXでサーバと通信するにはちょうど良いわけです。

ちなみに、JavaFXでもHTML(XML)やJSONのサポートはしています。ですが、現時点ではパーサーを書くのが少々面倒なので、オブジェクトに変換可能なAMFライブラリは便利です。今後はJavaFXでも簡単に変換できるライブラリが出るとは思いますが。

非同期通信

アプリケーションの起動と同時にグラフのコンポーネントは描画されますが、データをサーバから取得する処理は非同期で行っています。取得が終わるとbind機能を使いデータが反映されるわけです。このようなバックグラウンドの処理が簡単にマルチスレッドで書けるのはJavaFXの強みのひとつでしょう。

エラー

明日も早いので貼り付けるだけ・・・。

01:12:51.031 [task.1] DEBUG o.t2framework.commons.module.Modules - modules initialized
java.lang.ExceptionInInitializerError
at org.t2framework.commons.meta.impl.BeanDescImpl.init0(BeanDescImpl.java:123)
at org.t2framework.commons.meta.impl.BeanDescImpl.init(BeanDescImpl.java:107)
at org.t2framework.commons.meta.impl.BeanDescImpl.(BeanDescImpl.java:93)
at org.t2framework.commons.meta.spi.DefaultBeanDescCreatorImpl.createBeanDesc(DefaultBeanDescCreatorImpl.java:48)
at org.t2framework.commons.meta.BeanDescFactory.createBeanDesc(BeanDescFactory.java:205)
at org.t2framework.commons.meta.BeanDescFactory.getBeanDesc(BeanDescFactory.java:148)
at org.t2framework.commons.meta.BeanDescFactory.getBeanDesc(BeanDescFactory.java:118)
at org.t2framework.t2.format.amf3.io.writer.impl.Amf3TypedObjectWriterImpl.writeClassReferenceDefine(Amf3TypedObjectWriterImpl.java:104)
at org.t2framework.t2.format.amf3.io.writer.impl.AbstractAmf3ClassObjectWriterImpl.writeClassReference(AbstractAmf3ClassObjectWriterImpl.java:33)
at org.t2framework.t2.format.amf3.io.writer.impl.Amf3TypedObjectWriterImpl.writeClassObject(Amf3TypedObjectWriterImpl.java:80)
at org.t2framework.t2.format.amf3.io.writer.impl.Amf3TypedObjectWriterImpl.writeInlineObject(Amf3TypedObjectWriterImpl.java:113)
at org.t2framework.t2.format.amf3.io.writer.impl.AbstractAmf3ObjectWriterImpl.writeObject(AbstractAmf3ObjectWriterImpl.java:80)
at org.t2framework.t2.format.amf3.io.writer.impl.AbstractAmf3ObjectWriterImpl.writeAmf3Data(AbstractAmf3ObjectWriterImpl.java:39)
at org.t2framework.t2.format.amf3.io.writer.impl.AbstractAmf3ObjectWriterImpl.writeAmfData(AbstractAmf3ObjectWriterImpl.java:33)
at org.t2framework.t2.format.amf3.messsage.writer.impl.AmfMessageWriterImpl.writeData(AmfMessageWriterImpl.java:110)
at org.t2framework.t2.format.amf3.messsage.writer.impl.Amf3RequestMessageWriterImpl.writeBody(Amf3RequestMessageWriterImpl.java:55)
at org.t2framework.t2.format.amf3.messsage.writer.impl.AmfMessageWriterImpl.writeBodies(AmfMessageWriterImpl.java:89)
at org.t2framework.t2.format.amf3.messsage.writer.impl.Amf3MessageWriterImpl.write(Amf3MessageWriterImpl.java:33)
at org.t2framework.t2.format.amf.spi.impl.AmfMessageProcessorImpl.writeRequestMessage(AmfMessageProcessorImpl.java:317)
at org.t2framework.t2.format.amf.client.AmfConnection.call(AmfConnection.java:143)
at org.t2framework.t2.format.amf.client.AmfConnection.call(AmfConnection.java:88)
at org.sapporojava.example.t2javafx.client.TemperatureListWorker.run(TemperatureListWorker.java:28)
at com.sun.javafx.async.TaskImpl.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkMemberAccess(Unknown Source)
at java.lang.Class.checkMemberAccess(Unknown Source)
at java.lang.Class.getDeclaredMethods(Unknown Source)
at org.t2framework.commons.meta.impl.BeanDescSupport.init(BeanDescSupport.java:119)
at org.t2framework.commons.meta.impl.BeanDescSupport.(BeanDescSupport.java:47)
... 29 more

追記

ソースを確認したところ、この部分

private static void init() {
    ignores.addAll(Arrays.asList(Object.class.getDeclaredMethods()));
}

確かにセキュリティ例外は発生する箇所ですね・・・。
これまでApplet上のコードでリフレクションを使うなんて事なかったからノーマークでしたが、結構厳しい制限になるのかもしれないなぁ。
証明書は年間数万だし、困った。