- PR -

簡単なJSPソースなんですが。。。

投稿者投稿内容
fuku
会議室デビュー日: 2004/10/26
投稿数: 10
投稿日時: 2006-02-01 17:55
こんにちは。

初心者向けのJSP研修資料を作成しているのですが、
変数の有効範囲を説明するため、
下記のようなソースを作り、実行させようと思っています。

これを実際にIEで実行すると、
再読み込みをする度に iの値は順調に増えていくのですが、
3〜20までのカウントの中で一度初期値に戻ってしまいます。
初期値に戻った後は100以上カウントしても正常に動作します。

何度も見直したり、キャッシュを消してみたりしたのですが、ダメでした。
なぜ初期値に戻ってしまうのかをネットでもいろいろ調べたのですが、
解決できる内容が見つけられなかったので、皆さんの力をお借りできればうれしいです。

≪JSP≫
<%@ page contentType="text/html;charset=Shift_JIS" %>
<%!
int i=1;
%>
<%
i += 1;
out.println(i + "<br>アクセスすると増える");
%>

≪動作環境≫
Win XP
Tomcat5.5.12
jdk1.5.0_06

Apache2.0.55もインストールしていますが、研修環境は上記環境にするため、
Tomcatのみ起動させて使用しています。

ソースに間違えがあったというポカなのかもしれませんが、
視点の固まってしまった自分では見つけにくくなっているかもしれないので、
ご協力お願いいたします。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-02-02 02:33
単純にリロードしていくだけで戻ってしまいますか?

JSPになにか変更を加えて再コンパイルされてしまっているということはないでしょうか。
techbits
会議室デビュー日: 2006/02/02
投稿数: 10
投稿日時: 2006-02-02 07:10
static int i=1;
とやっても変わりありませんか?
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-02-02 07:38
初回アクセスで2が表示されるのはちょっと気になりますね。関係ないですが。

static イニシャライザと、JSPのインスタンス作成時にデバッグ文が表示されるようにしてみました。
コード:
<%@ page contentType="text/html;charset=Shift_JIS" %> 
<%! 
  static{
    System.out.println("initializing");
  }
  int i=0; 
  static int staticInt = 0;
  Object obj = new MyObject();
  class MyObject extends Object{
    MyObject(){
      System.out.println("new JSP instance is instantiated");
    }
  };
%> 
<% 
  i++; 
  staticInt++;
  out.println(i + ":"+staticInt); 
%>



時々新しいJSPのインスタンスが作成されることが分かりますね。
-----
initializing
new JSP instance is instantiated
new JSP instance is instantiated
-----
fuku
会議室デビュー日: 2004/10/26
投稿数: 10
投稿日時: 2006-02-02 10:56
インギさん、techbitsさん
ありがとうございます。

staticを付けることで現象は回避できました。

同一ユーザーから同一ファイルへのアクセス時に
一度だけインスタンス生成が行われると思っていました。
そこが落とし穴だったんですね^^;

JSPのインスタンス生成の仕組み(タイミング)について
まだ理解できていない状態ですが、そこは別で調べてみます。
でも、その辺を理解するのに適した本などありましたら、
教えていただけるとうれしいです。

ありがとうございました。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-02-02 11:00
なんで複数の JSP インスタンスをつくるのかはわかりませんが・・・。JSPのインスタンスが生成されるまでのコールスタックを表示させれば読むべきソースの位置がわかります。
コード:
   MyObject(){
      System.out.println("new JSP instance is instantiated");
new Throwable().printStackTrace();
    }



uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2006-02-02 13:09
「JSPはサーブレットに変換される」「サーブレットのインスタンスは使いまわされる」
「宣言で定義した変数は(staticを付けなければ)インスタンス変数になる」ことは理解されて
いるでしょうか。

また、この変数をどんな目的で使用されているのかわからないのですが、ユーザ単位あるいは
セッション単位でカウントアップするようにしたいのであれば、static変数を使うようにする
のは不適当です。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-02-02 16:03
>でも、その辺を理解するのに適した本などありましたら、
>教えていただけるとうれしいです。
そりゃなんといっても仕様書でしょう。
暗記する必要はないので一通り手元に揃えておいていつでも参照できるようにしましょう。

JSP2.0仕様より
引用:

JSP.1.1.4 Translation and Execution Phases
<snip/>
In the execution phase the container manages one or more instances of this
class in response to requests and other events.



Servlet2.4仕様より
引用:

SRV.2.2 Number of Instances
For a servlet not hosted in a distributed environment (the default), the servlet
container must use only one instance per servlet declaration. However, foraservlet implementing the SingleThreadModel interface, the servlet container may instantiate multiple instances to handle a heavy request load and serialize requests to a particular instance.



「JSPは複数のインスタンスを作っても良い」「サーブレットはインスタンス一つだけ」みたいです。
#SingleThreadModel はServletSpec2.4ではdeprecatedです

スキルアップ/キャリアアップ(JOB@IT)