- - PR -
WAS上のサーブレットで画像描画処理を行うとNoClassDefFoundErrorが発生します。
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2004-03-02 22:52
WebSphereをご存知でないとわからない内容ですがご容赦ください。
WebSphere5.0 RedHat Linux という組み合わせで、サーブレット上でJPEGの描画処理を行うと [04/02/25 23:45:05:633 JST] 712e0be4 WebGroup E SRVE0026E: [サーブレット・エラー]-[sun/awt/motif/MToolkit]: java.lang.NoClassDefFoundError: sun/awt/motif/MToolkit というエラーが発生してしまいます。 皆様もご存知かとは思いますがsun.awt.motif.MToolkitは /opt/WebSphere/AppServer/java/jre/lib/rt.jar に入っていてrt.jarはWebSphereのブートストラップクラスパスに含まれています。 (SnoopServletで確認) ですのでNoClassDefFoundErrorが発生する原因が全くわからず困っています。 その上環境変数のクラスパスにrt.jarを追加したり外したりしているうちに正常 に動く場合がありました。(現状では環境変数のクラスパスからrt.jarを外した 状態で正常に動いています。) 他のフォーラムで質問した時にはクラスローダーを勉強してくださいという指摘 をいただきました。 ですのでクラスローダーについて勉強したのですが、rt.jarはブートストラップ クラスローダーにロードされているはずなので、warのクラスがロードされている 子供のクラスローダーからは参照可能なはずという理解しかできませんでした。 原因の解明に至る事ができませんでした。 sunのAWTの代替としてPJAも検討したのですがLinux上では一部のクラスで問題が ありJavaVMが落ちてしまうので使用できません。 どなたかクラスローダーに詳しい方がいらしたらこの問題の原因と解決方法をご 教授ください。 ちなみに確認用のサーブレットとして以下のクラスを作成しました。 クラスをうまくロードできていない時はToolkit.getDefaultToolkit() で落ちてしまいます。 import java.awt.Toolkit; import java.awt.print.Printable; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @version 1.0 * @author */ public class TestServlet extends HttpServlet { /** * @see javax.servlet.http.HttpServlet#void (javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.print(Toolkit.getDefaultToolkit()); writer.flush(); writer.close(); } } 以上、よろしくお願いします。 | ||||
|
投稿日時: 2004-03-03 00:31
スタックトレースだけ見るとクラスパスの問題に見えますが、
Xサーバに接続しようとして失敗したのが本当の原因のような気がします。 以下のスレッドが参考になると思います。 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?forum=12&topic=8200 ちなみに上記のスレッドではJ2SE1.4のヘッドレスモードを使って解決していましたが、 田中さんの場合、PJAはだめ、また、WAS5.0ということでヘッドレスモードも使えなさそうなので、 Xvfbはどうでしょうか。 | ||||
|
投稿日時: 2004-03-03 10:45
ご返答ありがとうございます。
ご指摘いただいたように昔はXサーバーへの接続に失敗していました。 当時は以下のようなエラーが発生していました。 [04/02/25 18:46:31:547 JST] 9a36930 WebGroup E SRVE0026E: [サーブレット・エラー]-[Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.]: java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable. at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method) とほぼ同時に [04/02/25 18:47:05:453 JST] 9a36930 WebGroup E SRVE0026E: [サーブレット・エラー]-[sun/awt/motif/MToolkit]: java.lang.NoClassDefFoundError: sun/awt/motif/MToolkit も発生していました。 しかしその後Xサーバーへの接続の失敗は xhost + で解決していて発生しておりません。(セキュリティ上問題があるのですが・・) その後はNoClassDefFoudErrorのみ出続けています。 しかし当時のログをよく見てみるとサーバーの起動直後にサーブレットにアクセスすると [Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.] が発生して後はいくらアクセスしても java.lang.NoClassDefFoundError: sun/awt/motif/MToolkit が出続けていたようです。 ですのでご指摘のようにまだXへの接続の設定で問題があるのかもしれません。 もう少しXの設定方法を調べてみます。 (ちなみにその後xhost -で接続制限を復活させてもサーブレットが正常に動くことが あるのでなおのこと混乱しています。) Xvfbはお客様がLinuxの運用にキャラクターログインしか許さない場合は検討してみよう と考えています。 後は最悪の場合はAWTの使用をやめてSWTを使うことも考えています。 ただSWTを使ってもXへの接続の問題は残る可能性は高いのですが・・・・ 以上、ご返答ありがとうございました。 | ||||
|
投稿日時: 2004-03-03 11:16
unibon です。こんにちわ。
#WebSphere は分かりませんが。
私も rt.jar にあるのだから別段のことは要らないような気もします。 NoClassDefFoundError が出るのなら、あまりたいしたことではないのですが、とりあえず System.out.println(sun.awt.motif.MToolkit.DATA_TRANSFERER_CLASS_NAME); みたいなことを事前にやって MToolkit クラスをロードしてみてはどうでしょうか。 なお DATA_TRANSFERER_CLASS_NAME はとりあえず目に付いた public なフィールドであり、これに拘るわけではないですが。 これでなにか挙動に変化があるかもしれません。 | ||||
|
投稿日時: 2004-03-03 12:10
ご返答ありがとうございます。
ご指摘いただいた点なのですが恐らく System.out.println(sun.awt.motif.MToolkit.DATA_TRANSFERER_CLASS_NAME); を実行した時点でNoClassDefFoundErrorが発生すると思います。 私が最初の投稿時に記入させていただいたサンプルのサーブレットでは同等の処理 を行っていまして writer.print(Toolkit.getDefaultToolkit()); は内部でsun.awt.motif.MToolkitをロードしています。 うまくいくと画面に sun.awt.motif.MToolkit@xxxxxxx が表示されるのですが ロードに失敗するとNoClassDefFoundErrorが発生して落ちてしまいます。 強制的にロードさせたいのはやまやまなのですが、ブートストラップクラスローダー がrt.jarを掴んでいるので、ブートストラップクラスローダーがロードに失敗すると WAR内のクラスでいかにコーディングしようともロードは出来なさそうです。 先ほど実際に作業している人間から報告を受けたのですが以下の順番で作業をすると うまくいったようです。 1.rootでRedHatにログイン 2.Xを起動 3.(xhost +などで)Xを開放 4.環境変数のクラスパスにrt.jarを追加 5.WASを起動 ただし他のマシンで同様の作業を行ったところうまくいかないことがあったとも聞きま した。 個人的には4.の作業はいらないはずだと思うのですが担当者は必要だったと言ってい ます。 もう少し検証してみます。 以上、ご返答ありがとうございました。 | ||||
|
投稿日時: 2004-03-03 12:59
私も4.の作業は不要なように思います。これでうまくいくとのことですが、 うまくいかなかったという当初の手順はどのようになってましたか? それと比較すると何が問題なのか見えてくると思います。 それと、Xサーバへの接続ですが、Xサーバが必要なのは最初の1回だけで、 それ以降はXサーバを落としてもAWTは動作する、という記述をどこかで 読んだ気がします。Xvfbの設定に関するどこかのページに書いてあったような…。 ただし、この話は出典を失念した上試していないので、 噂話やヨタ話レベルのものだと判断してもらってもかまいませんが | ||||
|
投稿日時: 2004-03-03 19:18
unibon です。こんにちわ。
#WebSphere に加えて、あと X window もあまり知りません。
素朴な疑問なのですが、スタックトレースは出ないのでしょうか。WebSphere が隠しているのでしょうか。それとももともと NoClassDefFoundError のときはスタックトレースが出ないものなのでしょうか。 Java の中で NoClassDefFoundError を throw している箇所は10箇所程度しかないと思うので、どこなのかが分かればなにか手がかりになるかも、と思ったのですが。 | ||||
|
投稿日時: 2004-03-03 20:28
unibon です。こんにちわ。
Toolkit.getDefaultToolkit のソースコードを見たところ、かなり複雑な場合分けをやっているみたいです。また、その中に Class.forName や ClassLoader が垣間見えることから考えると、sun.awt.motif.MToolkit クラスのクラス変数にアクセスしてクラスがロードされるやりかたは、少し異なるかもしれません。 | ||||
