home ホーム search 検索 -  login ログイン  | help ヘルプ

find 検索

1081 - 1090 / 1320    [|<]  [|<]  [<]  101  102  103  104  105  106  107  108  109  110   [>]  [>|][>|]
タイトル/名前 更新者 更新日
java_static_final_test.zip msakamoto-sf 2009-04-05 10:42:58
sjis_dangerous_chars.txt msakamoto-sf 2009-04-05 10:42:44
日記/2006/11/02/JavaでPropertyファイルを好き勝手な位置から読み込ませるには msakamoto-sf 2009-04-05 10:38:44
日記/2006/11/06/WebLogicでのJMSキューの最大メッセージ数 msakamoto-sf 2009-04-05 10:35:52
日記/2006/11/06/WebLogicのServletでディレクトリ指定無しのファイル出力位置は? msakamoto-sf 2009-04-05 10:27:29
日記/2006/11/06/WebLogicのクラスパスに独自クラスパスを追加したい場合 msakamoto-sf 2009-04-05 10:23:22
技術/Java/static finalを使用する場合の注意点 msakamoto-sf 2009-04-05 10:21:24
技術/Java/URLConnectionとTimeoutによる自動リトライ msakamoto-sf 2009-04-04 10:27:19
技術/Linux/VMwareのゲストOS時にXが800x600でしか立ち上がらない場合 msakamoto-sf 2009-04-04 10:23:18
技術/Java/Tomcat上でJSPをJDBでデバッグとか。 msakamoto-sf 2009-04-04 10:21:35
ソート項目 / ソート順     1ページ 件ずつ表示

java_static_final_test.zip  

所有者: msakamoto-sf    作成日: 2006-11-06 10:20:11
カテゴリ: Java 添付ファイル 
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-05 10:42:58
md5:2f9f0999a8ff67dff2c511b6fda18725
sha1:23f6fce5649c115af918308997ffb17977d0a6ea

sjis_dangerous_chars.txt  

所有者: msakamoto-sf    作成日: 2009-04-05 10:42:20
カテゴリ: 添付ファイル 
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-05 10:42:44
md5:8dde063e813d61faba10b040e333e978
sha1:ebcaa5a65a0fe8d0bc22af8906d5c2ddff94ab69

日記/2006/11/02/JavaでPropertyファイルを好き勝手な位置から読み込ませるには  

所有者: msakamoto-sf    作成日: 2006-11-02 10:37:17
カテゴリ: Java 

前々から気になってて仕方の無かった疑問の一つ。
Propertyファイル・・・広く言えば外部リソースという言い方になるらしいんだけど。
例えばクラスパス直下の*.propertiesファイルであれば、ResourceBundleで一発で読み出せる。ResourceBundleは基本的にローカライズリソースの読み込みに使われるので、まあ、便利。
ただ、ResourceBundleはプロパティファイルの位置を指定できない。クラスパスツリーの中に組み込まれた形でないと利用できない(元々リソースを表現するクラスファイルを読み込むものらしいので、当然と言えば当然)。
というわけで、好き勝手な位置のiniファイルやpropertiesファイルをどうやって読み込ませようか、となるわけだけど、Log4jの初期化部分とか眺めて大雑把に3種類くらいありそう。

1. ClassLoaderのgetResource()をそのまま利用する。→これだとやっぱりクラスパスツリーの内部にしかおけない・・・。
2. URLクラスの形で指定し、Properties#load()に、URL#openStream()を指定する。
3. 普通にjava.io.FileInputStream()を作成し、Properties#load()に指定する。

1. はクラスパスツリー限定になるので不可。なんだってこう、Javaのリソースの取り扱いってクラスパス主義なのかね。Perl/Ruby/PHP/Pythonの方が融通が利く。そういうところは。
2. については、結局のところファイル指定の部分がURL経由か、手動でFileInputStreamを作るか、ってところだけで、結局は同じ。そうすると、URL経由だと

file:///c:/hogehoge/bohebohe/hoge.properties

みたいにやたら冗長に指定することになる。めんどくせー。

・・・まあ、DOSから動かすのであれば

file:///%CD%/../../hoge.properties

とか指定できるからあながち困るわけでも無いんだけど。

結局のところ、URL経由か直かの違いだけで、クラスパスツリーの外に設定ファイルを置こうとしたらProperties#load()を使用するほか無いのかもしれない。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-05 10:38:44
md5:ac0528798ac326f89c174aca937d154f
sha1:be4a45e0ef65b05119960a13ddbf5fd89de4d5d4

日記/2006/11/06/WebLogicでのJMSキューの最大メッセージ数  

所有者: msakamoto-sf    作成日: 2006-11-06 10:29:30
カテゴリ: Java 

WL9.X系でJMSを使うことになりまして、まあ今まで色々調べてきたんですが、ついつい忘れがちになってしまいそうな部分を。

Q. JMSキューの最大メッセージ数はどこで指定できるのか/されているのか?
A. JMSサーバーの「コンフィギュレーション」→「しきい値と割り当て」→「割り当て」の「最大メッセージ数」で指定できます。(キュー自体ではなくJMSサーバーの設定に属するらしい)

これを超過すると、以下のような例外がプロデューサ側で発生します。

weblogic.jms.common.ResourceAllocationException: 
weblogic.messaging.kernel.QuotaException: 
Quota JMSServer-0.Quota.1162782914171 exceeded: Request: 58 bytes. 
Quota: bytes = 156 / 9223372036854775807 messages = 6 / 6 
policy = FIFO outstanding blocking request false

同じ設定画面に「しきい値」というのもあります。例えばここで指定した「最大メッセージしきい値」を超えると、WebLogicのログに以下のログが出力されます。

<2006/11/06 12時21分15秒 JST> <Alert> <JMS> <BEA-040026> <JMSServer "JMSServer-0" で、
送り先 SystemModule-0!Queue-0 のメッセージのしきい値を超過しました。>

また、受信側が動いてメッセージを刈り取っていき、「最小メッセージしきい値」を下回ると、WebLogicのログに以下のログが出力されます。

<2006/11/06 12時21分53秒 JST> <Alert> <JMS> <BEA-040027> <JMSServer "JMSServer-0" で、
送り先 SystemModule-0!Queue-0 のメッセージのしきい値条件をクリアしました。>

ちなみに「一つのメッセージは最大何バイトまでか」については、キューの「コンフィギュレーション」→「しきい値と割り当て」→「割り当て」の「最大メッセージサイズ」で設定可能です。(再起動不要)

メッセージをずらずらと送信していくと、おおよそ指定したメッセージサイズほど送信し終えた後の送信で、

weblogic.jms.common.ResourceAllocationException: 
weblogic.messaging.kernel.QuotaException: Maximum message size exceeded - 
allowable size for kernel is 2147483647, and allowable size for destination 
is 32 and your message's size is 33

というログが出力されました。
受信側では、この例外が出たメッセージだけ、受信できませんでした。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-05 10:35:52
md5:8d6978c9b84c1b664249538f2075d489
sha1:11e82d66cc266db3d3f6d88751ba947985c9a164

日記/2006/11/06/WebLogicのServletでディレクトリ指定無しのファイル出力位置は?  

所有者: msakamoto-sf    作成日: 2006-11-06 10:25:01
カテゴリ: Java 

仕事の関係上、WebLogicのServletから、ディレクトリ指定無しでファイルを書き込んだとき、そのファイルはどこに作成されるのか調べる必要が発生した。

取り急ぎ実験用のServletを組み、実際にどこに出力されるのか確認してみる。

PrintWriter fout = null;
try {
    fout = new PrintWriter(new FileWriter("abc.txt", true));
    fout.println("aaaaa" + System.currentTimeMillis());
} catch(Exception e) {
    e.printStackTrace(out);
} finally {
    try { fout.close(); } catch(Exception e) {}
}

実験してみたところ、どうやらいわゆる$DOMAIN_HOMEに出力されているようである。特に意識せずインストールした場合は、/opt/bea/user_projects/domains/(ドメイン名)/以下、といったところか。

実際問題、起動スクリプトを叩いたのはWebLogicを実行可能なユーザーのホームディレクトリ上であるが、作成されたのはDOMAIN_HOMEである。

これは、$DOMAIN_HOME/bin/setDomainEnv.sh(cmd)で

Win:
pushd %LONG_DOMAIN_HOME%
Unix:
pushd ${LONG_DOMAIN_HOME}

として実装されている。・・・ご丁寧に、Win/Unix共にシェルスクリプト内でpushd/popdが独自実装されている。非常に興味深い。

以上より、特にsetDomainEnv.shを弄っていない限り、ディレクトリ指定無しのカレントディレクトリは$DOMAIN_HOMEとなる事が分かった。・・・当然、$DOMAIN_HOMEにはロックファイルの作成権限があるため、すくなくともカレントディレクトリ(=$DOMAIN_HOME)自体には書き込み権限があるということになる。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-05 10:27:29
md5:ecb736b0a5089d8e49db338da44217ef
sha1:89bf14a1fd6eb05ec945696597e6ef02774339c7

日記/2006/11/06/WebLogicのクラスパスに独自クラスパスを追加したい場合  

所有者: msakamoto-sf    作成日: 2006-11-06 10:22:24
カテゴリ: Java 

WebLogic9.x系のsetDomainEnv.sh(cmd)では、"EXT_PRE_CLASSPATH" と "EXT_POST_CLASSPATH" の二つの環境変数により、起動直前位のタイミングでCLASSPATHの前後に独自クラスパスを追加できるようになっている。

UNIX:
if [ "${EXT_PRE_CLASSPATH}" != "" ] ; then
    PRE_CLASSPATH="${EXT_PRE_CLASSPATH}${CLASSPATHSEP}${PRE_CLASSPATH}"
    export PRE_CLASSPATH
fi
if [ "${EXT_POST_CLASSPATH}" != "" ] ; then
    POST_CLASSPATH="${POST_CLASSPATH}${CLASSPATHSEP}${EXT_POST_CLASSPATH}"
    export POST_CLASSPATH
fi

Windows:
if NOT "%EXT_PRE_CLASSPATH%"=="" (
    set PRE_CLASSPATH=%EXT_PRE_CLASSPATH%;%PRE_CLASSPATH%
)
if NOT "%EXT_POST_CLASSPATH%"=="" (
    set POST_CLASSPATH=%POST_CLASSPATH%;%EXT_POST_CLASSPATH%
)

上記のPRE_/POST_CLASSPATHが、最終的にWebLogicのjarを起動するjavaコマンドのクラスパス指定に使用される。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-05 10:23:22
md5:ffff19707e3179e8e168e049d79314e4
sha1:fba8f5b6f78483a2b36bff484ce2cf1079cf2fc0

技術/Java/static finalを使用する場合の注意点  

所有者: msakamoto-sf    作成日: 2006-11-06 10:07:45
カテゴリ: Java 

public static final を定数として使用していた。
定数の値を変えてpublics static finalを定義しているクラスをコンパイルし、それを参照している、例えばmainクラスなどを起動しても、変更が反映されない。変更前の値を使用してしまう。

という現象に悩まされていました。で、試しに次のような定数クラスを用意し、適当にそれらのフィールドを出力するmainクラスを作成してみる。 ここで重要なのは、定数クラスと mainクラスは別々のJavaソース、クラスファイルになっている点。

public class ConstTest {
public static final String const1 = "const1-1";
public static final int const2 = 123;
public static final String getConst3() { return "const3-1"; }
public final String getConst4() { return "const4-1"; }
public String getConst5() { return "const5-1"; }
public static String const6 = "const6-1";
public final String const7 = "const7-1";
}

やってみたところ、明らかになったのは、finalで宣言されたpublic staticなフィールドについては、どうもインライン展開され、呼び出し側のクラスに直値が書き込まれてしまうらしい、と言うことである。直接そのことが明記されている文章は、JavaHouseに一件見つかった。残りは、finalメソッドについてのインライン化について取り上げられており、finalフィールドについては少々うやむやである。

http://java-house.jp/ml/archive/j-h-b/026215.html
http://www.nextindex.net/java/private.html
http://www.nextindex.net/java/perform/tips.html
http://www-06.ibm.com/jp/developerworks/java/030117/j_j-jtp1029.html
http://www-06.ibm.com/jp/developerworks/java/030627/j_j-jtp04223.html

どちらにせよ、static finalにしてしまうと、参照側のクラスにインライン展開されてしまっている為、元クラスのstatic final値を変更した場合、参照側のクラスも再コンパイルが必要であることには変わりはなかった。

・・・そうか・・・。WebLogicで、プロジェクト共通の定数クラスの値だけ変えても、Servlet側で反映してくれなかったのはこれが原因だったのか・・・。

このインライン化は、finalされたクラスを直接.classで参照していようと、jarファイルの中であろうと関係なく行われるようである。試しに先の実験用のfinalクラスをjar化し、main側を再コンパイルし、

javap -l -s -c -verbose mainクラス

として逆アセンブルした結果を、.class直接参照してコンパイルしたmainクラスの逆アセンブル結果とdiffしてみたところ、相違点は無かった。
つまり、jarファイルの中から参照しているクラスを探し、適切にfinalフィールドをインライン展開できていた。

public static finalの組み合わせ自体は昔から使われてきた手法である。にも関わらず、今までこの問題が表面化してこなかったのは何故か、非常に疑問に思う。特に、先に示したJavaHouseの記事については1999年のものである。・・・何でだろう。もしや、javacがある程度参照の連携を自動認識し、参照・被参照クラスをコンパイルしてくれるのではあるまいか?・・・そういわれれば、今回この現象が発覚したのは、被参照クラスと参照クラスを、別ディレクトリで管理していたからかも知れない。被参照クラスはAppサーバ側の設定で直接classpathを切ってしまっており、参照クラスはServletである。当然、コンパイル時のディレクトリ構造も別になっており、ServletクラスはCLASSPATHで被参照クラスを探索するようになっていた。

まあ、逆にfinalがインライン化されて取り込まれてしまう、という事が、徒に公開クラスの定数をpublic static finalにしてしまうとその後値を迂闊に変更できなくなる、という事にも結びつく。
Log4jのLogManager#DEFAULT_CONFIGURATION_KEYなどがdeprecatedになっていてもなお、消えることが無いのも、finalであるが故に、利用アプリのクラスでインライン展開されてしまっている可能性があるからであろう。log4jのjarを入れ替えればそれで済む話ではなくなってしまっているのだ。

検証用に用いたクラス・ソースツリー一式 : java_static_final_test.zip
hoge.bakみたいなディレクトリは、元はhogeディレクトリ。hoge.jarはhogeディレクトリをjarでまとめたもの。念のためhogeディレクトリはhoge.bakにリネームしただけ。



プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-05 10:21:24
md5:76603be6ef9569ca2b014ad97f08b227
sha1:5014a191876e356d89efa22d0a7161890a0809c2

技術/Java/URLConnectionとTimeoutによる自動リトライ  

所有者: msakamoto-sf    作成日: 2007-01-06 10:24:07
カテゴリ: Java ネットワーク 

http://satoshi.kinokuni.org/tech/Java_Network.html
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=23425&forum=12&3
などで、結構頻繁に取り扱われている。かくいう自分も、atmarkitの記事と同様の現象に心当たりがある。つまりクライアントでURLConnectionを使用した場合、接続がリトライするともう一度リクエストがくるように見えるときがある、という話。

現在の仕事で、実際、Timeout?な形の異常系でリトライが走っていて、気になった。う~~ん・・・TCPレベルでも再送はあるんだけど、何かSSLレベルから綺麗にリトライしているところが気になる。で、Googleを眺めてみると。

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4772077

・・・ありました。
※2007/01月時点では「Will fix in Tiger」と書かれ、statusは"closed, fixed"になっていた。
2009/04月時点では"10-Fix Delivered"となっているので、恐らく修正版がリリースされていると思われる。



プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-04 10:27:19
md5:f28a03d0dc714f565e7eb8970d469d57
sha1:0eb3a33df220033f7f1cbf35d513a5a809d9d4a5

技術/Linux/VMwareのゲストOS時にXが800x600でしか立ち上がらない場合  

所有者: msakamoto-sf    作成日: 2009-02-15 13:41:23
カテゴリ: Linux VMware 

CentOS5.1で困ってた事象ですが、ようやく解決しました。

Windowsホスト上でVMwareでLinuxを使うことが多いのですが、CentOS5.1を使っていて、Xが800x600の低解像度でしか立ち上がらずにどうにも困っていました。
また、VMwareToolsのインストールとかバージョンアップを繰り返している内に /etc/X11/xorg.confが壊れたかどうかしたらしく、そもそもstartx時にエラーが出たりして上手く動きません。

SSHは動くので不自由はしないのですが、PuTTYで使っていると2-30分すると何故か接続が切れてしまうというこれまた謎の現象が発生しています。うー、VMware5の初期バージョンから使ってて、何度もVMware5のマイナーバージョンアップを繰り返したり、途中でNAT中心にしたりまた止めたりしてNW周りも弄っているので、そこら辺でしょうか・・・。

とにかくSSH側でもそんな問題を抱えてたので、なるべくXを使えるなら使いたかったのですが、800x600じゃさすがにお話にならない。

というわけで漁っていたら、ようやく見つかりました。


ポイントはMonitorセクションで "HorizSync 1.0 - 10000.0" "VertRefresh 1.0 - 10000.0"の指定だと思われます。
実際自分の場合も、Monitorセクションだけがxorg.confに欠落していたので、そこだけコピペしたところ無事1024x768でXが起動しました。

Section "Monitor"
    Identifier "Monitor0"
    HorizSync 1.0 - 10000.0
    VertRefresh 1.0 - 10000.0
EndSection

このセクションが無かったときは、/var/log/Xorg.0.logに次のようなログが出ていました。

(II) VMWARE(0): <default monitor>: Using default hsync range of 31.50-37.90 kHz
(II) VMWARE(0): <default monitor>: Using default vrefresh range of 50.00-70.00 Hz
(II) VMWARE(0): Clock range:   0.00 to 400000.00 MHz
(II) VMWARE(0): Not using default mode "640x350" (vrefresh out of range)
...(以下、Not using が続く)
(II) VMWARE(0): Not using default mode "1280x800" (bad mode clock/interlace/doublescan)
(II) VMWARE(0): Not using mode "1024x768" (no mode of this name)
(--) VMWARE(0): Virtual size is 800x600 (pitch 800)

一方、上記Monitorセクション追記後は次のように変化しています。

(II) VMWARE(0): Monitor0: Using hsync range of 1.00-10000.00 kHz
(II) VMWARE(0): Monitor0: Using vrefresh range of 1.00-10000.00 Hz
(II) VMWARE(0): Clock range:   0.00 to 400000.00 MHz
(II) VMWARE(0): Not using default mode "320x175" (bad mode clock/interlace/doublescan)
...(以下、Not using が続く)
(II) VMWARE(0): Not using default mode "1152x768" (width too large for virtual size)
(--) VMWARE(0): Virtual size is 1024x768 (pitch 1024)
                                ^^^^^^^^^^^^^^^^^^^^^

という感じです。

ちなみに、xorg.confの設定は弄る機会も殆ど無い為よく分からなかったのですが、
http://www.linuxtopia.org/online_books/centos_linux_guides/centos_linux_reference_guide/s1-x-server-configuration.html
とかが良くまとめられています。いえ、たまたまGoogleでHITしただけなんですけど。
探せば一杯出てくるだろうなあ、それより本家ドキュメント先に見ろよという感じですが。

とりあえず以上。



プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-04 10:23:18
md5:d8fd5077ee6c0e7cbb33dc11285363c6
sha1:10d10322bc173069640d41a63cec0c877102e487

技術/Java/Tomcat上でJSPをJDBでデバッグとか。  

所有者: msakamoto-sf    作成日: 2007-02-25 15:13:44
カテゴリ: Java 

お仕事のヘルプでJSPをデバッグしたい(但しEclipse抜き)とのこと。
ということで、取り急ぎTomcatの環境と、JSPのデバッグ?できるような基本的なサンプルを用意してみる。先方の環境として、JDK1.4(1.3?)、Tomcat4(多分、4)とのことなので、取り急ぎ合わせる。

OS TurboLinux 10 Server
Java J2SDK 1.4.2_13
Tomcat 4.1.34

Tomcat 環境

本筋と関係のないディレクトリは省いている。とりあえずで良いので、ユーザはrootで、いい加減でも動けば良いみたいなノリ。

/opt/in_vitro/apps/apache-tomcat-4.1.34/ ... 以降、TOMCAT_HOME
    bin/ ... 起動・停止シェルスクリプト
    conf/ ... XML設定ファイル
    logs/
        catalina.out ... System.out, System.err (標準出力・標準エラー出力)のダンプ
        localhost_****.YYYY-MM-DD.txt
         ... TomcatのLoggerおよび各App毎のLoggerの出力するログファイル?
    webapps/
         ... Tomcatが自動ロードしてくれるWebappのディレクトリ
    work/
         ... JSPコンパイルディレクトリ他、Tomcatが汎用的に使用するテンポラリディレクトリ
        Standalone/
            localhost/

JSPサンプル

動けば良いので、webapps/以下に直接rootユーザーで作ってしまう。

  • 配置ディレクトリ
    • TOMCAT_HOME/webapps/test
  • JSP
    • TOMCAT_HOME/webapps/test/index.jsp
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8">
<title>test</title>
</head>
<body>
<%-- 変数xを宣言 --%>
<%! int x = 0; %>
<%-- スクリプトレット内でforループ処理を実行 --%>
<%
for (int i = 0; i < 10; i++) {
        x++;
        System.out.println("i=[" + i + "]");
        System.out.println("x=[" + x + "]");
}
%>

<%-- 式で実行結果を表示 --%>
<H3>計算結果:<%= x %></H3>
</body>
</html>
    • TOMCAT_HOME/webapps/test/WEB-INF/web.xml
<?xml version="1.0" ?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
</web-app>
  • 出力
    • 画面上には太字で「計算結果:10」と出力される。
    • TOMCAT_HOME/logs/catalina.out に、"i=..."と"x=..."が出力される。

コンパイルされたJSPはどこか?

以下の様に、各WebApps毎にディレクトリが自動作成され、保存される。

TOMCAT_HOME/work/Standalone/localhost/
    admin/...
    manager/...
    test/ ←今回作成したWebapp用
        index_jsp.java
        index_jsp.java

なお、JSPコンパイルディレクトリは<Context>タグの"workDir"属性で変更することができる。 その場合、workDirで指定されたディレクトリにJSPがコンパイルされ、出力される。*1

Tomcatをデバッグ用に起動

Tomcatといえども基本はJVMに他ならない。従ってJDBのリモートデバッグが可能である。javaコマンドのオプションとして、リモートデバッグオプションを追加し、リモートのJDB(およびその互換デバッグクライアント:Eclipse, NetBeansなど)からのデバッグ接続を受け付けるようにする。

参考HP

では、このデバッグオプションを追加してTomcatを起動するにはどうすればよいか?まず、Tomcatの起動・停止のコアであるcatalina.sh(.bat)を参照する。

TOMCAT_HOME/bin/catalina.sh
  • 冒頭で、JAVA_OPTSという環境変数を参照していることが分かる。
#   JAVA_OPTS       (Optional) Java runtime options used when the "start",
#                   "stop", or "run" command is executed.
  • 実際に起動・停止している部分が下部にある。
elif [ "$1" = "start" ] ; then

  shift
  touch "$CATALINA_OUT"
  if [ "$1" = "-security" ] ; then
    echo "Using Security Manager"
    shift
    "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
      -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
      -Djava.security.manager \
      -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
      -Dcatalina.base="$CATALINA_BASE" \
      -Dcatalina.home="$CATALINA_HOME" \
      -Djava.io.tmpdir="$CATALINA_TMPDIR" \
      org.apache.catalina.startup.Bootstrap "$@" start \
      >> "$CATALINA_OUT" 2>&1 &

以上より、予めJAVA_OPTSという環境変数を設定しておくことで、javaコマンドに任意のオプションを渡せることが分かった。

以下に示すとおり、実験してみる。

# JAVA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=9000,server=y,suspend=n"
←デバッグを有効にし(-Xdebug)、TCPソケットで、ポート番号9000で受け付ける(-Xrunjdwp:...)。
# export JAVA_OPTS
# echo $JAVA_OPTS
-Xdebug -Xrunjdwp:transport=dt_socket,address=9000,server=y,suspend=n
# cd ${TOMCAT_HOME}
# ./bin/startup.sh
Using CATALINA_BASE:   /opt/in_vitro/apps/apache-tomcat-4.1.34
Using CATALINA_HOME:   /opt/in_vitro/apps/apache-tomcat-4.1.34
Using CATALINA_TMPDIR: /opt/in_vitro/apps/apache-tomcat-4.1.34/temp
Using CATALINA_OUT:    /opt/in_vitro/apps/apache-tomcat-4.1.34/logs/catalina.out
Using JAVA_HOME:       /opt/in_vitro/apps/jdk1.4

psコマンドおよびnetstatコマンドで確認してみると、javaが上り、デバッグポートで指定した9000番をlistenしているのが分かる。

# ps a
...
2431 pts/0    S      0:06 /opt/in_vitro/apps/jdk1.4/bin/java -Xdebug -Xrunjdwp transport=dt_socket,address=9000,server=

# netstat -npl -t
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN      2431/java
tcp        0      0 0.0.0.0:9000            0.0.0.0:*               LISTEN      2431/java <<< デバッグポート
tcp        0      0 0.0.0.0:8009            0.0.0.0:*               LISTEN      2431/java
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      2431/java

JDBでJSPをデバッグ

以下、駆け足で上記までに整えた環境でJSPを、JDBでデバッグしてみる。

JDBはJavaSDKに付属するコマンドラインデバッガである。詳細は下記URL参照。
http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/tooldocs/solaris/jdb.html

簡易かつ一般的なJDBによるコマンドラインデバッグ手順

  1. jdbでローカル又はリモートのJVMに接続する。
    1. ローカルの場合は、コマンドラインオプションから "-attach <portno>" のように、単純にローカルJVMがLISTENしているポート番号を指定する。
    2. リモートの場合は、コマンドラインオプションから "-connect com.sun.jdi.SocketAttach:hostname=<ipaddr>,port=<portno>" のように、<ipaddr>でリモートマシンのIPアドレスを指定し、<port>でデバッグソケットをLISTENしているポート番号を指定する。
  2. "use <directory>"か、JDB起動時に"-sourcepath <directory>"としてデバッグしたいクラスに対応するソースディレクトリの位置を指定する。
  3. "stop in <full-package-class-name>.<method>"や"stop at"をしてブレークポイントを仕掛ける。
  4. アプリを動かす。
  5. ブレークポイントで止まると、その旨JDBのコマンドラインに表示される。
  6. 以降、"list", "next", "continue", "dump", "where" などのコマンドを用いデバッグしていく。
  7. 終了は"quit"

なお、JDBはJVMへの接続に数種類の方法をサポートしている。この箇所だけ事情によりJDK1.5の説明になってしまうが、

$ jdb -listconnectors

でサポートされている接続方法(Connectorと呼ぶ)と、使用可能なパラメータの説明が表示される。共有メモリ経由の接続もあるようで、興味深い。

TomcatがコンパイルしたJSPのデバッグ

今回、TomcatがコンパイルしたJSPをデバッグするに辺り、トラブルになった箇所がある。この点もまとめると、以下のような手順でJSPをデバッグした。

  1. まず、非常に重要な注意点として、 TomcatはJSPを一括して"org.apache.jsp"パッケージ配下としてコンパイルする 点に注意する。
    1. しかしながら、Tomcat4( 付記参照 )はJSPファイルを TOMCAT_HOME/work/Standalone/localhost/(webappname)/ の直下にコンパイルする。
    2. →つまり、パッケージ名とディレクトリ構造がずれてしまっている。 *2
    3. 従って、以下の様に、workディレクトリに対するシンボリックリンクを作成し、"org/apache/jsp"ディレクトリのように見せかける必要がある。
# cd /tmp
# mkdir -p org/apache
# ln -s /tmp/org/apache/jsp /opt/in_vitro/apps/apache-tomcat-4.1.34/work/Standalone/localhost/test
  1. 上記のようなディレクトリ処理を行った後、以下の様にJDBを起動し、TomcatのJVMにアタッチする。
$ jdb -attach 9000 <<< 今回は9000でデバッグポートをLISTENしている。
> use /tmp
> stop in org.apache.jsp.index_jsp._jspService
  1. Webからアクセスすると、途中で止まり以下のようになる。
Breakpoint hit: "thread=http-8080-Processor3", org.apache.jsp.index_jsp._jspService(), line=21 bci=0
http-8080-Processor3[1] list <<< "list"と入力しENTER
17
18      public void _jspService(HttpServletRequest request, HttpServletResponse response)
19            throws java.io.IOException, ServletException {
20
21 =>     JspFactory _jspxFactory = null;
22        javax.servlet.jsp.PageContext pageContext = null;
23        HttpSession session = null;
24        ServletContext application = null;
25        ServletConfig config = null;
26        JspWriter out = null;
  1. 後はJDBのデバッグコマンドでデバッグし、デバッグを終了したいとき(プロセスからデタッチしたいとき)は"quit"コマンドを実行する。

付記:TomcatのJSPコンパイラについて

本文中でも挙げたが、Tomcat4.1.34の場合、コンパイルされたJSPがworkDirの直下にできてしまい、パッケージ名とのズレが発生した。 ところが、他で使用しているTomcat 5.5.17 の場合は問題なく org/apache/jsp ディレクトリが作成され、その中にできていた。
実際のところはTomcatで使用されているJasper(JSPコンパイラ)周りのコードを紐解く必要がある。時間の都合上今はできないが、少なくともメジャーバージョン間ではいろいろ変わっているのかも知れない。*3

また、JSPのデバッグを行う場合にはJSPのコンパイル自体をdebugモードONで行わせる必要がある。また、メソッド内のローカル変数を表示させたい場合、javacで"-g"オプション付きでコンパイルされている必要がある。
Tomcat4の場合はデフォルトでその辺りのデバッグオプションが有効化されているようである。また、TOMCAT_HOME/conf/web.xmlの設定によりデバッグオプションを無効化したり、JSPファイルのポーリング周りについても調整可能らしい。

以下に、Tomcat4.x/5.0.x/5.5.x/6.0.x でのJSP設定についての本家ドキュメントへのリンクを示す。


*1: デフォルトではTomcatは.javaファイルは削除しないようである。WebLogicの場合、デフォルトでは削除されてしまう為、web.xml/weblogic.xmlなどで固有の設定を行う必要があった。
*2: 先ほどの例だと、index.jspは org.apache.jsp.index_jsp クラスになるが、どこにも org/apache/jsp といったディレクトリ構造は作成されていない。
*3: もっとも、自分の経験上は少なくとも5.5.x以上を使用すればディレクトリの問題は解消されるようである。

プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2009-04-04 10:21:35
md5:956fe56444bd1a9945fb9abd67bc577e
sha1:1b3132e0016bbd51c5bc9a8fae146d9f817de76d