ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Java質問&情報提供サイトコミュのサーブレット+WebLogicでTomcatの起動エラー

  • mixiチェック
  • このエントリーをはてなブックマークに追加
すみません、自力でエラーを解決出来ないのでわかる方がいらっしゃったら教えて下さい。ソースもここに直接コピーしようと思ったのですが、ファイル数が多いので代わりにこちらにアップしました。見て頂けると助かります。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9181.zip

今、やろうとしていることはサーブレットからEJBを使ってOracle接続し、データを取ってきて表示させることです。環境は、WebLogic/Oracle10g/Linuxを使用しています。

問題は、Tomcatを起動出来ない事です。エラー発生までの手順は以下の通りです。
上記のURLのディレクトリ一式を$CATALINA_HOME/webapps/配下にコピーし、Makefileを使用してコンパイル。コンパイルは問題なく終了し、このMakefileで同時にWebLogicへのデプロイも行っています(コンソール上で"Product"(これはEJB名です)がデプロイされることを確認しました)。しかし、肝心のTomcatを起動出来ません。Tomcat Managerを見るとmyapplicationが表示すらされていません。catalina.outを確認されたところ以下のようなエラーが出力されていました。

May 16, 2009 3:06:10 AM org.apache.catalina.startup.HostConfig deployDirectory
SEVERE: Error deploying web application directory myapplication
java.lang.NoClassDefFoundError: examples/product/ServletJDBCEJB : % (wrong name ServletJDBCEJB)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1
847)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:890)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1354)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1094)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:992)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4058)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4371)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:792)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:527)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:494)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1056)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)

という訳で、クラスが見つかっていないようです。パッケージ関連の基本的な問題のような気がするのですが、Javaの知識も浅く、どこをどう修正すればいいのかがよくわかりません。とりあえず、examples/productを認識出来ていない事が問題なのだと思い、web.xmlの<servlet-mapping>にexamples/productを加えてみたところ、エラーが以下のように変わりました。Tomcatマネージャを見ると、myapplicationは表示されるようになりました。しかし、起動状態がfalseのままでtrueになってくれません。

May 16, 2009 3:14:48 AM org.apache.tomcat.util.digester.Digester endElement
SEVERE: End event threw exception
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor18.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tomcat.util.IntrospectionUtils.callMethodN(IntrospectionUtils.java:953)
at org.apache.catalina.startup.CallMethodMultiRule.end(WebRuleSet.java:789)
at org.apache.tomcat.util.digester.Rule.end(Rule.java:229)
at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1140)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.endNamespaceScope(XMLDTDValidator.java:2077)
at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.handleEndElement(XMLDTDValidator.java:2028)
at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.endElement(XMLDTDValidator.java:901)
-------------------------------------------------------------------------------------------------------------
(補足)
上記のURLにProductClient.javaというファイルも添付していますが、このファイルはServletJDBCEJB.javaの代わりに使用すると問題なく動作するものです。参考のため添付致しました。ProductClient.javaはサーブレット経由ではなく、単純にJavaコマンドから実行するものですが、WebLogicに登録しているデータソースを使用してOracleに接続し、データを取得してコンソールに表示できました。ServletJDBCEJB.javaはこのソースを単純にdoGet()内にコピペしただけの普通のサーブレットファイルです。

本件は環境依存の問題ですが、もしWebLogic+サーブレットを使用した経験のある方など何か調べる指針でもございましたら教えて下さい(本件は単純にJavaのパッケージだけの簡単な問題なのかも知れませんが。。)アドバイス宜しくお願いします。

コメント(11)

クラスパスが通ってない
通っていてもクラスローダーが異なる
9181.zipを簡単に見ました。

Makefileの次の行が怪しいです。

  $(JAVAC) -d $(CLIENT_DIR) $(BEAN_API) $(BEAN_CLIENT)

-dの次がbuildでなければいけないと思います。
ご確認ください。
皆様レスありがとうございます。状況を整理して返信しようと思ったのですが残念ながら進展がありませんでした。とりあえず、たぁぼさんにご指摘頂いた$(JAVAC) -d $(CLIENT_DIR) $(BEAN_API) $(BEAN_CLIENT) については試してみたのですが結果は変わりませんでした。
それから、らららさんとじゅんちさんにご指摘頂いたWLのServletコンテナですが、何らかの理由があってトムキャットを使っていた訳ではなく、全く知らなかったからです。。

WebLogicやEJBが何たるかもほとんど理解出来ていないまま、コードを動かしながら理解しようと取り組んでいたところでした。とりあえず、WLのサーブレットコンテナを動かそうと、WLのマニュアルを一通り読んだのですが、どうも私の使っているWL(10.3)にはサーブレットの設定画面すら見つからず何をどうしたらいいかわからなかくなってしまいました。

とりあえずもう1、2日グーグルして状況整理に努めます。
今は何を質問すればいいかすらわかっていませんので。。

とりあえずサーブレットからEJB起動は敷居が高いので、まずは段階を踏んでコンソールからEJBを起動してデータベースアクセスするように目標を変更しました。既にデータベースにアクセスするサンプルソース自体は手元にあるのですが、あまりに原始的なのでこれをもう少し汎用的な感じに改造したいと思っています。しかしどのように手をつければいいかよくわかりません。
(動作する手持ちのサンプルソース)
http://www.dotup.org/uploda/www.dotup.org46495.zip.html

前回アップしたURLは既にファイルが削除されていたので再度上記のURLにアップし直しました。上記のサンプルソースは、コンソールから引数なしで実行するとProductsというテーブルから情報を取得して画面に表示します。(なお、Productsというテーブルは
SQL> DESC PRODUCTS
NAME VARCHAR2(50)
PRODUCTID VARCHAR2(50)
DESCRIPTION VARCHAR2(50)
BASEPRICE NUMBER(38)
という構成になっています。)
これを、引数としてDMLを文字列で渡して実行すると結果を表示するように改造したいと考えています。例えば
SELECT NAME, PRODUCTID FROM PRODUCTS;や
INSERT INTO PRODUCTS VALUES('test', 'test', 'test', 0);や
DELTETE FROM PRODUCTS;
といった文字列を渡すとSELECTなら相応の結果を画面に戻し(例えば項目はカンマ区切りなどで)、INSERT/UPDATE/DELETEなら更新した行数を画面に表示したいようにしたいです。
要は、以前、サーブレットでデータベースにJDBCアクセスし、画面に結果を表示するプログラムを作成したのですがこんな感じのことをしたいです。(以下以前作成したサーブレットのdoGet内の処理)
try {
// index.htmlから文字列を受けとり、PreparedStatementを作成
out.println("<TABLE BORDER=\"1\">");
PreparedStatement pstmt = conn.prepareStatement(str);
// (1) Queryの場合は1を返す
if(pstmt.execute()) {
ResultSet rset = pstmt.getResultSet();
ResultSetMetaData meta = rset.getMetaData();
out.println("<TR>");
for(int i=1; i<=meta.getColumnCount(); i++) {
out.println("<TH>" + meta.getColumnName(i) + "</TH>");
}
out.println("</TR>");
while(rset.next()) {
out.println("<TR>");
for(int i=1; i<=meta.getColumnCount(); i++) {
out.println("<TD>" + rset.getString(i) + "</TD>");
}
out.println("</TR>");
}
out.println("</TABLE>");
} else { // (2) Query以外の場合
out.println(pstmt.getUpdateCount() + " 行が更新されました。");
}
}
catch ( Exception e)
{ e.printStackTrace(out); }
out.println("</BODY></HTML>");
out.close();
}

上記のロジックは、今回のEJBの場合、ProductClient.javaに書くことになると思うのですが、ここでわからないのは、PreparedStatementやResultSetなどをEJBではどのように扱えばいいのかがよくわかりません。添付の中にxmlファイルが4つありますがどこかで何らかの定義が必要でしょうか?理解度が低く恐縮ですがご教示頂きたいです。宜しくお願いします。
> 7
サーブレットだろうがスタンドアロンJavaアプリケーションだろうが、EJBの使い方は基本的には同じになるはずです。ただし、今回のように外部から呼び出しするためにはいろいろとテクニックが必要なので、同一アプリケーションサーバ内で呼び出すようにされたほうが簡単だと思います。
それから「PreparedStatementやResultSetなどをEJBではどのように扱えばいいのかがよくわかりません」ということですが、そもそもCMP Entity Beanで実装されていますので、開発者がPreparedStatementやResultSetを意識する必要はありません。
(※ CMP:Container Managed Persistenceの略。永続化に関する処理(DB処理等)をコンテナで管理するという意味。)
EJBにどのような振る舞いをさせるかは ejb-jar.xml に記述します。


目標を変更されるのは構いませんが、先に根本の原因を見つけないと同じ失敗を繰り返す可能性があります。プログラムを何とかして動かしたい気持ちはわかりますが、そもそもやり方自体が間違っていたとしたら元も子もないですよ。
同じでしょ。DBアクセスするって言う目的を果たすだけなら
(WLSのコネクションプールの恩恵には預る必要が無いなら)別に直接生のJDBC使ってもいいし。(普通はやらないけど)
上でおっしゃるように、永続化BEANを使ってもできるでしょ。(普通はそうするよね)
ただ主さんの書き方を見ると、MVCがごちゃごちゃになって、頭のなかで整理されてないんじゃ無いかしら。表示とDBアクセスがごちゃ混ぜになってるから、いきなり戸惑うのでは?

戸惑いどころがちょっと不自然かと思います。


結果報告です。

サーブレットからEJBの起動を行い、またデータを取って来てHTML形式にしてクライアントのブラウザに表示出来るようになりました。サーブレットからEJBの起動が出来なかったのは設定漏れがあったようです。(環境の管理者に問い合わせたところそういっていました。詳しくは聞いていませんが)

とりあえず、これでEJB3のCMPを使って基本的なことが出来るようになりました。
これから一週間かけてServlet + EJB(CMP) + CORBAを組み合わせた簡単なアプリケーション作成に入ります。また困ったら新規にトピを作ってご質問させて頂くかも知れませんがよろしくおねがいします。有り難うございました。

p.s.
始めて知ったのですが稚内北星学園という学校の丸山先生という人のEJBに関する資料が豊富で内容も充実していたのである程度理解が進みました。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Java質問&情報提供サイト 更新情報

Java質問&情報提供サイトのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング