sola's note -11ページ目

sola's note

日ごろのメモを書いていきます。何か新しいものを作るために。

Webアプリケーションを作成しようと、いざ設計して、
詳細設計に入ろうと思ったら

JSPのファイル名ってどうすりゃいいんだ

という状態に陥った。
問題点は、次の通り

Slim3において

・JSPはControllerと1:1で存在する

・ControllerはリクエストURLと特定の規則でURLマッピングされている
http://sites.google.com/site/slim3documentja/documents/slim3-controller/url-mapping

・Antで自動生成するJSPとControllerは、特定の命名規則で関連付いている

というのがあります。
何が問題かって言うと、Antで自動生成する場合、
JSPファイル名にhoge-fugaと書こうものなら
Controller名が

Hoge-fugaController

となるわけです。
あくまで個人の見解だと、
上記のファイル名は

Javaファイルとして心理的に受け入れ難い

ものがあります。
あまり仕事でコーディングした事が無いので、
PGとしての暗黙のルールor鉄則があるかどうかは知らないのですが、

正直かなり避けたいところです。

じゃあ、実際どんな問題があるかというと、
アカウントを作る画面があったとして、

create_user.jsp

なんてのを連想すると、

Create_userController

というController名になってしまう。
逆にController側に立って、

crreateUser.jsp

と考えると、
見事

CreateUserController

というController名になります。
こうなると、実に馴染み(?)があるクラス名なんですが、

Slim3の特徴であるURLマッピングを考えると
上記Controllerへのリクエストは

http://xxxxxxx/createUser

となると思います。
気付かれる方は気付かれるかもしれないですが、
これは

URL的に正しい表記なの?

という疑問が出てきます。
(大文字小文字の観点で。)

まあ、なんだかんだ書きましたが、
目指すところ

・CreateUserControllerとcreate_userのURLマッピング

または

・名詞が2連続で先頭以外小文字でもわかりやすい命名方法

です。
残念ながら現時点で結論は出ていません。

***

GAEの本はいくつか買っているけれど、
本格的に開発に取り組むにあたり3冊目買ってみました。

すっきりわかるGoogle App Engine for Javaクラウドプログラミング/中田 秀基
¥3,360
Amazon.co.jp
以前買ったひがさん監・著のSlim3の本よりGAEの技術的な事が書かれています。
使い分けとしては、
Slim3の本→データストアの設計・利用
この本→GAE周りの技術
という感じです。

オープンソース徹底活用 Slim3 on Google App Engine for Java/ひが やすを
¥2,730
Amazon.co.jp




設計やってばかりで、全然プログラム触れていない
考えているだけで実態が出来てこないというのはなかなかのストレス。

ということで、ちょっとした疑問を解消するため
ちょっとしたプログラムを。

プログラムを書いている時にたまに気になるのが、
変数の初期化をどのタイミングで行うか。
メモリーの管理方法によって、処理速度が変わるんだと思うけど、
どんな感じで定義すべきなのか。

出来るだけギリギリまで定義しないのか、
使おうと思ったら、定義しちゃうのか。

スコープの問題もあるから、一概には言えないと思うけど、
とりあえず3パターンで実験。

import java.util.Date;

public class TimeCounter {

    public static void main(String[] args) {

        TimeCounter tc = new TimeCounter();

        for (int i = 0; i < 5; i++) {
            System.out.println("----------演算開始----------");
            tc.test001();
            System.out.println("演算終了");
            System.out.println();
            System.out.println();
        }
    }

    private void test001() {
        System.out.println("文字列初期化と負荷テスト開始");
        System.out.println();

        Date btime1 = new Date();
        Date atime1 = new Date();
        Date btime2 = new Date();
        Date atime2 = new Date();
        Date btime3 = new Date();
        Date atime3 = new Date();

        // *********************************************************
        System.out.println("*****nullで初期化の処理開始*****");
        btime1 = new Date();
        for (int i = 0; i < 1000000000; i++) {
            String str = null;
            str = "testtesttesttesttesttesttesttesttesttest";
        }
        atime1 = new Date();
        System.out.println(atime1.getTime() - btime1.getTime());
        System.out.println("nullで初期化の演算終了");
        System.out.println();

        // *********************************************************
        System.out.println("*****空値で初期化の処理開始*****");
        btime2 = new Date();
        for (int i = 0; i < 1000000000; i++) {
            String str = " ";
            str = "testtesttesttesttesttesttesttesttesttest";
        }
        atime2 = new Date();
        System.out.println(atime2.getTime() - btime2.getTime());
        System.out.println("空値で初期化の演算終了");
        System.out.println();

        // *********************************************************
        System.out.println("*****初期化のみ処理開始*****");
        btime3 = new Date();
        for (int i = 0; i < 1000000000; i++) {
            String str = "testtesttesttesttesttesttesttesttesttest";
        }
        atime3 = new Date();
        System.out.println(atime3.getTime() - btime3.getTime());
        System.out.println("初期化無し演算終了");
        System.out.println();

        System.out.println("文字列初期化と負荷テスト終了");
        System.out.println();
    }
}

処理は5回ループしているけど、
5回分の結果書いたら長くなるので、最初の1回で。

----------演算開始----------
文字列初期化と負荷テスト開始

*****nullで初期化の処理開始*****
1234
nullで初期化の演算終了

*****空値で初期化の処理開始*****
1156
空値で初期化の演算終了

*****初期化のみ処理開始*****
1141
初期化無し演算終了

文字列初期化と負荷テスト終了

演算終了

DateのgetTimeはミリセコンドなので、
ざっと、10億回処理しても1秒かそこらな事がわかる。

んで、値の比較なんだけど、
どうやら初期化のタイミングなんて誤差の範囲内らしい。
(少なくとも数10文字の文字列を扱うくらいなら。)
Slim3のプロジェクトをいじってたら

java.lang.ExceptionInInitializerError
at org.slim3.datastore.DatastoreFilter.doFilter(DatastoreFilter.java:68)

が出るように。
色々試したり、作り直したりしても変わってくれなかったので

もう耐えられるかヽ(`Д´)ノ

って思って、他のPCでやったら、あっさりいけた。
しかも、他のPCでやったやつと同期とったら、それもいけた。。。

一体なんだったんだと。
元となっているブランクプロジェクトのzipファイルは同じものを使用。
Eclipseも同じ。バージョンも同じ。プラグインもおn(ry

とりあえず見かけたエラーだけメモしておく。

Caused by: org.slim3.util.WrapRuntimeException: An error occurred while creating a new instance of the class(org.slim3.datastore.DatastoreDelegate). Error message: com.google.appengine.api.datastore.DatastoreServiceFactory.getAsyncDatastoreService(Lcom/google/appengine/api/datastore/DatastoreServiceConfig;)Lcom/google/appengine/api/datastore/AsyncDatastoreService;

org.slim3.util.WrapRuntimeException: An error occurred while creating a new instance of the class(org.slim3.datastore.DatastoreDelegate). Error message: com.google.appengine.api.datastore.DatastoreServiceFactory.getAsyncDatastoreService(Lcom/google/appengine/api/datastore/DatastoreServiceConfig;)Lcom/google/appengine/api/datastore/AsyncDatastoreService;

Caused by: java.lang.NoSuchMethodError: com.google.appengine.api.datastore.DatastoreServiceFactory.getAsyncDatastoreService(Lcom/google/appengine/api/datastore/DatastoreServiceConfig;)Lcom/google/appengine/api/datastore/AsyncDatastoreService;

ちなみに1つ目は

http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000598.html
***引用***
J2SEに含まれるクラスのひとつ。パッケージも含めたクラス名はjava.lang.ExceptionInInitializerError。
static初期化子内で例外が投げられた場合に投げられる。Errorクラスのサブクラスのため厳密には例外ではない。
******

とかいうではないか。
「厳密には例外ではない」

ふーん。そうか厳密には例外じゃないのか。

そうかそうか。

なるほどね。


意味ワカランヽ(´ー`)ノ


その他は、インスタンス生成時に事件が起きたよ

とか

そんなメソッドねーよ

とか

そんなんばっか。

多分Slim3のDatastoreクラスが機能していないという問題なんだろうけど、
検証するほど細かく問題が出てないんだよね。
何より今のプロジェクト

Datastore使ってねーし。。。

動くんだもん。意味ワカンナイw
時間があるときに少しずつ確認していこう。。。

P.S.残念な結果だけど、一通り綺麗にした後もう一度プロジェクト作成したら
現象が再発しなくなった。。。

再現しないから確認できないけど、
SVNで同期しているクラスパスがどこかに混ざってた可能性が一番考えられる。