今回も AWSとはあんまり関係ない話です。AWSは使いますが…。


Javaアプリケーションをネットワーク越しにリモートデバッグ(remote debugging)するための設定について記載します。

リモートデバッグを利用すれば、例えば「ローカルPCはLAN環境にあり、グローバルIPや そのポート番号を自由に利用できないが、それらを利用するプログラムをデバッグしたい」という要望を叶えることが出来ます。つまり、LAN外のサーバでプログラムを動作させつつ LAN内のローカルPCで IDE を利用することが出来ます。
具体的には、例えばSMTPプログラムのテスト/デバッグに利用します…(しましたw)。



・EC2の準備
EC2インスタンスを起動して、Java (JDK) をインストールします。
Oracle(Sun)の標準JDKでなく OpenJDK でも良いのであれば、AmazonLinux には標準で OpenJDK (1.6) がインストールされているので、ラクチンです。ここでは、AmazonLinux を利用しておきます。

セキュリティグループには、アプリケーションで利用する設定に加えて 22番ポートも追加しておいてください。
VPCを利用する場合、Subnet、Internet GateWay、Routing Table なども設定する必要があります。

OS によっては、SUSE やら iptables 等のファイヤーウォール/セキュリティ保護プログラムの設定も必要です。期待するプログラムが起動できなかったり、パケットが通過できなかったりするので…。
⇒ 例えば AWS にある redhat6.3 って、デフォルトで iptables によるフィルタが設定されてます…。sshd を邪魔しないとは思いますが…。redhat はコレが標準なのでしょうか?[謎]



・sshd の設定
リモートデバッグにはポートを1つ使用しますが、さすがにデバッグ用のポートをインターネットに直接公開するのは怖いので ssh 越しで利用します。
AmazonLinux だと 標準では ssh port forwarding が無効になっているので、有効にしておきます。
具体的には /etc/ssh/sshd_config にあるはずの AllowAgentForwarding のパラメータを yes に変更します。



・ssh 接続
リモートデバッグで使用するポートを1つ決めて、EC2へ ssh port forwarding 接続します。ここでは port 9999 を利用するものとします。
ssh接続元は、デバッガとしての NetBeans を起動するPCになります。
$ ssh \
     -L 9999:localhost:9999 \
     -l ec2-user \
     YOURHOSTNAME.amazonaws.com



・Java プログラムの起動

EC2側で Java プログラムをネットワーク越しにデバッグできるようにオプション付で起動します。
$ java \
     -Xdebug \
     -Xrunjdwp:transport=dt_socket,server=y,address=9999,suspend=y
     ....................

※アプリケーション依存のパラメータ指定などは、必要に応じて適切に指定してください。
-Xdebug は「デバッグモードを有効にする」というオプションです。
-Xrunjdwp:~は、リモートデバッグに使用する Java Debug Wire Protocol というものを設定します。コロン以降のパラメータも「-Xrunjdwpオプションの一部」なので、コンマの前後等に空白を入れないように注意してください。
-Xrunjdwpの各サブパラメータの意味は、以下のようになります。
transport : サーバ側の待ち受けに利用するソケットの名称
server : サーバモードにするか否か (y/n)
address : サーバ側で待ち受けに使用するポート番号
suspend : 起動時にデバッガが接続するまで実行を停止させるか否か (y/n)

ウマク起動出来たら、以下のような表示が見られます。
Listening for transport dt_socket at address: 9999

ちなみに、Javaのリモートデバッグ(JDWP)に関する詳細はコチラで閲覧できます。
http://docs.oracle.com/javase/1.4.2/docs/guide/jpda/conninv.html
http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/conninv.html
http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/introduction.html



・NetBeans からサーバ側 Javaプログラムに接続する
ssh接続元となっているローカルPC側で NetBeans を起動したら、デバッグする対象プログラムのソースコードをプロジェクトとしてロードしておきます。
その後、メニューから [デバッグ]→[デバッガのアタッチ] と辿って、サーバ側へ接続します。

netdebug_netbeans











サーバー側での設定に合わせますが、今までのサンプル通り起動しているなら上記のとおりでOKです。
※ ssh の port forwarding を使用しているので、 localhost:9999 が デバッグ対象のJavaプログラムが動作している AWS EC2 側の 9999 に直結されています。



・デバッグ
リモートデバッグが成立すれば、後はふつーにステップ実行などを行うだけです。
当然ですが、NetBeans 側のソースコードは実行中の Java プログラムとバージョンが一致している必要があります。

もしリモートデバッグが成立しない場合は、以下の点を確認ください。他にも確認項目はあるかもしれませんが、少なくとも自分(私!!!)がハマったのは以下のような点でした (^^;

1. Javaプログラムを起動しているサーバー側では ssh port forwarding を受け入れる設定になっているか?
⇒ /etc/ssh/sshd_config にある AllowAgentForwarding が yes になっていることを確認する。
$ sudo cat /etc/ssh/sshd_config  \
     | fgrep -i AllowAgentForwarding
AllowAgentForwarding yes

※これはAmazonLinuxの例です
2. Javaプログラムを起動する際のパラメータで、リモートデバッグ機能を有効にしているか?
$ java \
     -Xdebug \
     -Xrunjdwp:transport=dt_socket,server=y,address=9999,suspend=y
     ....................


※-Xrunjdwp:~ の行にあるコンマで区切られたパラメータの間には空白は入れないでください。
3. ssh の port forwarding が成立しているか?
⇒ NetBeans を起動している側のPCで netstat -avn | grep ':9999' を実行したとき、以下のような二行が表示されるか? (Windows7+cygwin の場合の例)
$ netstat -avn | grep ':9999'
TCP 127.0.0.1:9999 0.0.0.0:0 LISTENING
TCP [::1]:9999 [::]:0 LISTENING




なお、利用後は、EC2インスタンスをTERMINATEするか、STOPするのを忘れずに…。



AWS とは無関係ですが、AWS EC2 の利用例ということで、参考まで…。