2011年6月26日日曜日

第19回オープンラボ岡山

第19回オープンラボ岡山に参加したので、メモを残しておきます。
色々と抜けてたり、間違いもあると思いますが、参考程度に。
  • 昨日までは Tomcat 今日からは GlassFish
GlashFishがすごいらしい。
http://d.hatena.ne.jp/t_yano/20101227

Tomcatだと、色々なフレームワークが必要で、単体では使っていない。
→実は事足りてないんじゃないのか?
→GlashFishだといろんなフレームワーク等も含まれている。

Tomcatだと運用が大変じゃないか?
→1台ずつマシンにログインして設定が必要。
→GlashFishだと、1台のマシン(管理サーバ)にアクセスすれば全て管理可能。

TomcatユーザにおくるGlashFishのすすめ
1. 軽量
2. インストールが簡単(Zipを展開すればOK)
3. IDEとの連携が簡単
Eclipseプラグイン、NetBeansバンドル

GlashFish v3.1 vs Tomcat 7
・2011/01 Tomcat 7 安定版リリース、サポートなし
・2011/02 v3.1 本番向け、サポート有り
・2011/07 v3.1クラウド向け、Java SE 7

オープンソース版を使っても、製品版にアップグレードが可能。

再配備時にセッションを持続させる事ができる。
・オプション-keepSessions=trueに設定

GlashFishにおけるOSGiとHK2の役割
OSGiランタイム
・デフォルトApache Felixを使用(他のランタイムも動作する)

OSGiの採用によるメリット
・動的なモジュールの追加、削除
・拡張可能なアプリケーションサーバ
・任意のOSGiバンドルを利用可能

Grizzly
・ネットワークサーバアプリケーションのOSSプロジェクト
・Java NIOを採用
・サーバエンジンの実装
・Non Blockingの通信に対応(少ないスレッドで多くのリクエストを処理できる)

GlashFishの新機能について
・アプリケーションバージョンニング
→同一アプリケーションの複数配備
→asadminでバージョンの切り替え、有効なバージョンの確認も可能
・自己増殖クラスタ
→対象ノードへのインストールはSSH経由(SSHのデーモンとJDKがあれば可能)
自分自身をZipで固めてインストール
・WebSocketへの対応
→今までのやり方よりも、パフォーマンスが良い。

Java EE 6のベストセラー本もある。

まとめ:
・まずはお試し下さい。

質問:
・製品版GlashFishのサポート料は?
→パートナー経由での販売をしているので、パートナーに問い合せて下さい。
→WebLogicは大規模環境、GlashFishは先進性を求める時に。

JBoss AS7について
・起動が早い。(1.6秒)
・超軽量
・起動に必要なメモリ=12M
・Tomcat7は=8M。(ただし、サーブレットコンテナしか入っていない)

・管理容易性の向上
・設定ファイル(単一)
・API、GUI、CUIを容易

・作り直した理由
・クラウド前提
・Amazon EC2などを使ってみても、遅い。
・スタンドアロン
・ドメイン

・デモ
・2.7秒で起動(alpha3、少し汚れている)
・1.8秒で起動(beta4、スナップショット)
・管理画面はGWTベース

・arquillian(JBoss7から提供されるテストフレームワーク)
・JUnitのテストで簡単に記述が可能になる。

・JBoss Modules
・モジュール=JARを指す

・階層型クラスローダの問題
・上から実行するか、下から実行するか、両方動かすと簡単にデッドロック?

・スレッドコンテキストクラスローダ

・JBoss MSC
・JBoss Moduler Service Container
・AS7の新しいカーネル

質問:
・Amazon EC2での稼働実績などは?
→JBoss AS7のリリースがまだなので、実績はないが、10秒ぐらいでいけるのでは?

Java EE 6の詳細
・今後は本番環境へ
・今までは、お試しレベルだった。
・メインテーマ:開発生産性の向上

・仕様の削減
・古く使われなくなったAPIの整理
・コンポーネントのオプション化
・Java EE7で削除される可能性
・JAX-RPC→JAX-WS
・EJB Entity Beans→JPA
・JAXR
・JSR-88

・統合開発環境…

・Managed Bean 1.0
・@javax.annotation.ManagedBeanを指定
・コンテナによって管理
・他のJava EE コンポーネントのベース
・呼び出し元と同じスレッドで事項
・代表的なアノテーション
・@Resource
・@PostConstruct
・@PreDestroy
・JSR-250を参照

・Interceptors 1.1の使用
・自身のインターセプタクラスの作成

・Servlet 3.0
・web.xmlのオプション化
・アノテーションを使う。

・@WebServlet{name="hello"…}

・拡張性
・設定ファイルによる拡張
・web-fragments.xml
・サードパーティフレームワークの追加が容易
・プログラムによる拡張

・マルチパート対応
・@MultipartConfig

・非同期処理のサポート
・非同期リクエスト処理用のプログラムモデル
・長時間処理が必要なリクエストに有効
・Async用アノテーションを追加
・@WebServlet(asyncSupported=true)
・AsyncContext aCtx = req.startAsync(req, res);

・セキュリティの拡張
・認証/ログイン/ログアウト機能

・JavaServer Faces 2.0
・テンプレート機能
・Ajax対応
・JSFの仕様でJavaScript APIが定義
・<f:ajax execute="productname"…
・1行で対応可能
・ブックマーク可能なURL

・EJB 3.1
・JSR-318
・warファイルにEJBを含める事ができるようになった。
→まとめ方を考える必要がなくなる(EARなのか、WARなのか)

・Lite

・Full
・Lite + …

・標準化された Global JNDI名
・アプリケーションサーバによって、名前が違っていた。
・Java EE 6から
・JNDI名が標準化される。

・組み込み可能なEJBコンテナ
・javax.ejb.jar

・その他
・タイマーサービス

・Singleton Session Bean
・JVMをまたがらない、個々のJVMでのSingletonを保証

・JPA 2.0
・EJBの仕様から独立
・モデリングの強化
・@ElementCollection
・@CollectionTable(name="NICNAMES")
・組み込み可能型コレクション
・MapのCollection
・Criteria API
・クエリの制御をJavaオブジェクトで制御
・CriteriaBuilder
・EntityManager#getCriteriaBuilder()
・Metamodel API
・型チェックが強力
・コンパイル時に属性の有無、型チェックを実施

・JAX-RS 1.1

・Bean Validation 1.0
・アプリケーション中で宣言的なバリデーションが可能

・DI 1.0/CDI 1.0
・beans.xmlを必ず配置する。(デフォルト無効)

・Java EE 7に含まれる技術
・JPA 2.1
・JAX-RS2.0
・JMS 2.0
・JavaServer Faces 2.2
・WebTier
・HTML5
・WebSocket
・JSON API

質問:
・プロファイルの提供で、Webプロファイル以外に何かあるか?
→現時点ではWebプロファイルかFullしかない。
・アノテーションが増えたのは良いが、判別するためには、全クラスを
読み込んでおく必要があるので、遅いのでは?
→アノテーションスキャンは遅いです。
ただし、index化したりして早くする仕組みはあるだろう。

CDIを乗りこなせ
・JSR-299
・参照実装=Weld

・Portable Extension
・implements Extension
・Extensionは中身が空のインターフェイス

・Seam Catch
・例外ハンドリングを提供
・例外が発生したら、メソッドを実行されるようにする。

・Seam Faces
・JSFのフェーズコールバック

・Seam Solder
・はんだづけ
・Expression Languageを提供

・Seam Forge
・シェル環境を提供
・鍛冶場

と、ここで、MacBookProのバッテリーが残り少なくなったので
ここまででメモは終わり。

Desireでテザリングをしながらバッテリー駆動だと4、5時間程度で
残りがやばくなるようです。(だいぶ余裕を持って電源を切ったかもしれない(?))

2011年6月23日木曜日

設定アプリケーションから、アプリケーションの強制停止ボタンを押したら。

今日は、設定→アプリケーション→アプリケーションの管理→アプリケーションの詳細画面で
強制停止ボタンを押した時の挙動についてメモしておきたいと思います。

今回はAndroid2.2のソースコードを見た結果です。

ボタンを押すと、ActivityManager#forceStopPackage(String packageName)が
呼び出されます。

以下が、onClickメソッドの呼び出し元です。

} else if (v == mForceStopButton) {
            forceStopPackage(mAppInfo.packageName);

メソッド化されているのでその中身を見ると、確かにActivityManager#forceStopPackageが呼び出されているようです。

private void forceStopPackage(String pkgName) {
        ActivityManager am = (ActivityManager)getSystemService(
                Context.ACTIVITY_SERVICE);
        am.forceStopPackage(pkgName);
        checkForceStop();
    }
}

その後も、forceStopPackage()の中身も追いかけてみました。
ActivityManagerNative#getDefault()を呼び出しているようです。

public void forceStopPackage(String packageName) {
        try {
            ActivityManagerNative.getDefault().forceStopPackage(packageName);
        } catch (RemoteException e) {
        }
    }

getDefault()の中身は、よくわからないサービスが呼び出されていました。

static public IActivityManager getDefault()
    {
        if (gDefault != null) {
            //if (Config.LOGV) Log.v(
            //    "ActivityManager", "returning cur default = " + gDefault);
            return gDefault;
        }
        IBinder b = ServiceManager.getService("activity");
        if (Config.LOGV) Log.v(
            "ActivityManager", "default service binder = " + b);
        gDefault = asInterface(b);
        if (Config.LOGV) Log.v(
            "ActivityManager", "default service = " + gDefault);
        return gDefault;
    }

この後は結局見るのをやめたのですが、何かのサービスがいて、そのサービスが
プロセスをkillしているのかどうかは不明ですが、アプリケーションを終了させている
ようです。

サービスの中身は、以下のサイトに書いてあるような事がされているのでしょうか。
androidアプリをクリーンに終了させる方法
http://jp-shibax.air-nifty.com/blog/2010/05/android-e2dd.html

もう少し、ソースコードを追いかけてみる必要がありますが、
今日はこの辺でやめておきたいと思います。

2011年6月20日月曜日

Blogger上でソースコードに色をつけるための情報

Bloggerに移転するときに、「この機能が欲しい」と思っていたのが、
ソースコードを添付した時の色付け機能です。
ただ、Bloggerには標準で用意されているわけではないので、
自分でテンプレートを編集したりして、機能を追加する必要があります。
私は、Syntax Highlighterとgoogle-code-prettifyを導入しました。
ただ、Blogの背景が今のところ黒なので、Syntax Highlighterを利用することに
なりそうです。

ということで、導入までに参考にしたサイトが、以下のサイトです。
もし、同じ悩みがあれば、参考にしていただけたら幸いです。

あなたのソースコードを彩る、Syntax Highlighterまとめ
http://blog.37to.net/2007/06/syntax_highlighter/

BloggerにおけるSyntaxHighlighterの使い方
http://moririn-web.blogspot.com/2010/03/bloggersyntax-hilighter.html

Blogger でソースコードに色付けをする - google-code-prettify
http://jutememo.blogspot.com/2008/01/blogger.html

2011年6月19日日曜日

レイアウトのXMLに配置したButtonのOnClickがDialogだと使えない?

最近、ButtonのOnClickListenerを実装するのが面倒なので、レイアウトXMLのonClickを利用しているのですが、Dialogでも同じように使おうとしたところ、
以下のメッセージと共に、java.lang.IllegalStateException例外が発生しました。

「Could not find a method buttonClick(View) in the activity」

その時はOnClickListenerを実装した方が早かったので、深く調べなかったのですが、
たまたま思い出したので調べてみました。
※今回はAndroid2.2のソースコードを追いかけました。1.6でも同様の現象に
ぶち当たるのではないかと思います。

実際、レイアウトXMLのOnClickが設定される場所は、Viewクラスにあります。

case R.styleable.View_onClick:
                    if (context.isRestricted()) {
                        throw new IllegalStateException("The android:onClick attribute cannot " 
                                + "be used within a restricted context");
                    }

                    final String handlerName = a.getString(attr);
                    if (handlerName != null) {
                        setOnClickListener(new OnClickListener() {
                            private Method mHandler;

                            public void onClick(View v) {
                                if (mHandler == null) {
                                    try {
                                        mHandler = getContext().getClass().getMethod(handlerName,
                                                View.class);
                                    } catch (NoSuchMethodException e) {
                                        int id = getId();
                                        String idText = id == NO_ID ? "" : " with id '"
                                                + getContext().getResources().getResourceEntryName(
                                                    id) + "'";
                                        throw new IllegalStateException("Could not find a method " +
                                                handlerName + "(View) in the activity "
                                                + getContext().getClass() + " for onClick handler"
                                                + " on view " + View.this.getClass() + idText, e);
                                    }
                                }

                                try {
                                    mHandler.invoke(getContext(), View.this);
                                } catch (IllegalAccessException e) {
                                    throw new IllegalStateException("Could not execute non "
                                            + "public method of the activity", e);
                                } catch (InvocationTargetException e) {
                                    throw new IllegalStateException("Could not execute "
                                            + "method of the activity", e);
                                }
                            }
                        });
                    }
                    break;

handlerName変数には呼び出されるはずのメソッド名が設定されています。

ポイントは、以下のコードになります。

mHandler = getContext().getClass().getMethod(handlerName,
                                                View.class);

この部分で、クラス内にOnClickで設定したメソッドがあるかどうかを確認しています。
さて、今回の現象はActivityだとメソッドが発見できて、Dialogだと発見出来ないわけですから、getContext().getClass()で返されるクラスのインスタンスが違ってそうな気がします。
ということで、Dialog#onCreate(setContentView()を呼び出した直後)で

Log.d("TEST", "ClassName = " + getContext().getClass().getName());

なんてことをしてみました。

すると、出力されたログをみると、

ClassName = android.view.ContextThemeWrapper

と出力されました。

Activityだと同じ事ができないのですが、恐らく、getContext()がActivityのインスタンスを返すのだろうと思われます。

Activityのインスタンスであれば、自分で実装してあれば、メソッドが発見できますが、DialogでgetContext()するとContextThemeWrapperが返ってくるため、
OnClickのメソッドが発見出来ないわけです。

ちなみに、Dialog#getContext()が返す、Contextは、以下の通りです。
mContext = new ContextThemeWrapper(
            context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);

    public final Context getContext() {
        return mContext;
    }

ということで、結論は、「DialogではレイアウトXMLのOnClickは使えない」と言うことがわかりました。

DialogではおとなしくOnClickListenerを実装しましょう。