Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

ファイルのアップロードができない

・WindowsXP Professional Edition SP3 
・Eclipse Version: 3.3.2 + Pleiades for Eclipse
・Tomcat 6.0
・commons-fileupload-1.2.1
・commons-io-1.4 

の環境で、ファイルのアップロード
http://www.javaroad.jp/servletjsp/sj_servlet12.htm
を動かそうと考えています。

すると、ファイルデータ(FileItemオブジェクト)を取得し、Listオブジェクトとして返す部分、
List list = upload.parseRequest(request);
でcatchに入ってしまいます。

例外内容は、javax.servlet.ServletException 
原因は、java.lang.NoClassDefFoundError: javax/servlet/ServletInputStream です。

fileuploadをCLASSPATHで定義されているフォルダにセットしたり、WEB-inf\libにセットしているのですが、アップロードされません。
web.xmlやアップロードされたファイルを保持するフォルダも用意していますが、どうしてアップロードされないかわかりません。


恐れ入りますが、どなたかご教示願えないでしょうか。
よろしくお願いします。

56

回答

8970

閲覧

56件の回答

評価

0

classpathって何か知ってる?
その例外の意味は分かる?

評価

0

クラスローダーに読み込まれる順番で、
発生する場合があるらしい。

俺もあちこちに配置する場合があるが、
つか配置というよりもコピーするんだが。w

もし同じようにしてるんだったら、
WEB-INF/lib以外にコピーしたものを削除してみてはどうか。

評価

0

レスが遅くなりました。申し訳ありません。

$様
$様がおっしゃっているclasspathというのはWindowsの環境変数のことでしょうか。
例外の意味は、classpathにクラスが設置されていない。と認識しております。
環境変数には「.」(カレントディレクトリ)を入れていますし、そのクラスパスには;%CATALINA_HOME%\libを設定し、lib内にfileuploadをコピーしています。
#ここまで書いていて、違っていたら恥ずかしい(///)

不良社員様
>俺もあちこちに配置する場合があるが、
>つか配置というよりもコピーするんだが。w
確かに、ネットの情報よりfileuploadをさまざまな箇所においています。
ご指摘どおりWEB-INF/lib以外にあるfileuploadを削除して動かしましたが、やはり
例外内容:javax.servlet.ServletException 
原因:java.lang.NoClassDefFoundError: javax/servlet/ServletInputStrea
が戻りました。


お二方、ご回答ありがとうございました。

評価

0

>lib内にfileuploadをコピーしています。
NoClassDefFoundErrorは、何のクラスがないと言ってるのか、そしてそのクラスがどこのjarに入ってるのか、ちゃんと確認することが最低限。
エラーが出た=追加したjarがおかしいということでは必ずしもない。

評価

0

$様
$様の回答内容について、お尋ねします。
>NoClassDefFoundErrorは、何のクラスがないと言ってるのか、そしてそのクラスがどこのjarに入ってるのか、ちゃんと確認することが最低限。
とありますが、申し訳ありません。どのように確認していいかわかりません。
恐れ入りますが、確認方法をご教示願えないでしょうか。

評価

0

ひとつ確認したいんだが、
Servletのロジックは、Servletクラスを書いてるの?
JSPにスクリプトレットで書いてるの?

評価

0

不良社員様
Servletのロジックは、Servletクラスを書いております。
で、jspでServletクラスを呼び出す仕組みをとっています。
#http://www.javaroad.jp/servletjsp/sj_servlet12.htm
#の例では、Servletクラスを呼ぶのはjspじゃなくってhtmlですね。
#htmlじゃなくってjspだから例外が起きた…わけないですよね(汗)。

評価

0

参考になるかわかりませんが、TOMCAT3.?の頃、環境
変数CLASSPATHに設定しても、駄目なケースがありま
した。
その時は、クラスローダが違っていて駄目みたいという
ことでした。
また、TOMCAT5.Xではデフォルトでは環境変数CLASSPATH
は無視されるらしい。TOMCAT6.0ではどうなっているか
わかりません。

上記とは関係なく、以下のことを試して欲しいです。
($さんと不良社員さんの書かれていることをやった
あとで試してみてください。一度に全部やると訳が
わからなる可能性が高いので一つずつやっていって
ください。)

環境変数CLASSPATHから%CATALINA_HOME%\libを削除
してみてください。
そして、fileuploadのjarが一つになるようにしてく
ださい。

評価

0

>#htmlじゃなくってjspだから例外が起きた…わけないですよね(汗)。

他人に裏付けを欲しがるようなことじゃないな。
自分のやってることくらい、きちんと説明できるようにしようよ。

問題のクラスはJ2EEの標準クラスだろうから、
クラスパスの問題じゃなさそうなんだが。

後、考えられるとしたら、Tomcatのメジャーバージョンの違いだな。
Servlet/JSPのAPIバージョンだって違うだろうし。

Tomcat6との対応状況を確認してみては。
あと、サンプルを試す場合は、環境は同じものを用意するのが当然。
違う箇所は自己責任で。

評価

0

>問題のクラスはJ2EEの標準クラスだろうから、
>クラスパスの問題じゃなさそうなんだが。

確かに。でも通常、CLASSPATHに%CATALINA_HOME%\libを
設定することはまずないと思うんだけど。

評価

0

kj氏に突っ込んだ訳じゃないんだが。

俺としては、Tomcatそのものにはclasspathは利かないものと思ってる。

評価

0

kj様
環境変数CLASSPATHから%CATALINA_HOME%\libを削除
し、fileuploadのjarをWEB-inf\lib内に格納。その他のfileuploadのjarを削除し、Tomcatを再起動して動かしてみましたが、やはり結果は同じでした。

不良社員様
>他人に裏付けを欲しがるようなことじゃないな。
>自分のやってることくらい、きちんと説明できるようにしようよ。
シツレイシマシタ。

>Tomcat6との対応状況を確認してみては。
以前、ここの掲示板に、tomcat5.0とtomcat6.0
http://www.javaroad.jp/bbs/answer.jsp?q_id=20080610144757987
というタイトルで、やはりファイルアップロードできない旨書き込みがあり、質問者様が「できました」と書かれていましたので、アップロードはできるのではないかと考えます。

評価

0

最初に戻っちゃうけど、
ログに出力されてるエラーメッセージの、
最初の10行くらいをコピペしてよ。

評価

0

以下は、Eclipseのコンソールに表示されたエラーメッセージです。
--------------------------------------------------
2008/11/05 11:35:50 org.apache.catalina.core.StandardWrapperValve invoke
致命的: サーブレット UploadServlet のServlet.service()が例外を投げました
java.lang.ClassNotFoundException: javax.servlet.ServletInputStream
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)

評価

0

$さんの2008-11-05 09:54の発言をやってみてください。

やり方は、ネットで検索すればすぐわかるはず。

評価

0

あー、なんとなく分かった。

>ご指摘どおりWEB-INF/lib以外にあるfileuploadを削除して動かしましたが、

Tomcatの下じゃなくて、Tomcatが使うJDKのlibかなんかにも入ってない?

評価

0

$様
>Tomcatの下じゃなくて、Tomcatが使うJDKのlibかなんかにも入ってない?
ごめんなさい。Tomcatが使うJDKの場所を忘れてしまいました。
Tomcatが使うJDKの場所の探し方を教えてはいただけないでしょうか。
#もしそれが、システム環境変数のJAVA_HOMEをさすのであれば、そのフォルダ内にfileuploadがないのを確認しております。

評価

0

エクスプローラのメニューから検索した方が
速いし確実だと思う。

評価

0

使用しているEclipseはDドライブに保存されていますが、そのEclipseフォルダの下にserversフォルダがあり、そのフォルダ内にtomcat-6.0フォルダがありました。
その中にlibフォルダがあり、その中を見るとfileuploadがあったので、削除しました。
その後、すべてビルドし直して実行しました。
ですが、先ほどと同じメッセージ
---------------------------------------------------
2008/11/05 14:05:46 org.apache.catalina.core.StandardWrapperValve invoke
致命的: サーブレット UploadServlet のServlet.service()が例外を投げました
java.lang.ClassNotFoundException: javax.servlet.ServletInputStream
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
(以下略)
---------------------------------------------------
が出力されました。


kj様の、
>$さんの2008-11-05 09:54の発言をやってみてください。
というのは、javax.servletのjarファイルの中を見て、ServletInputStreamクラスがあるか確認する、という意味でよいのでしょうか。

評価

0

そうだけど。

よく見ると一番最初のエラーメッセージと異なって
いるね。

Tomcatの環境がおかしいかもしれないのでfileupload
はしばらくおいといて、別途、ServletInputStreamを
使うミニマムコードのServletを作ってどうなるか試し
てみてはいかかでしょうか?

評価

0

javax.servletで検索をかけたところ、2つの.jarファイルが見つかりました。
javax.servlet_2.4.0.v200706111738.jar
の中には、ServletInputStreamクラスがありましたが、
javax.servlet.jsp_2.0.0.v200706191603.jar
の中には、ServletInputStreamクラスはありませんでした。

>Tomcatの環境がおかしいかもしれないのでfileupload
>はしばらくおいといて、別途、ServletInputStreamを
>使うミニマムコードのServletを作ってどうなるか試し
>てみてはいかかでしょうか?
試しにやってみます。ありがとうございます。

評価

0

javax.servlet_2.4.0.v200706111738.jarが何なのか
私も知りません。誰か教えてください。

以下、スレの続きです。
%CATALINA_HOME%\libの中にservlet-api.jarがあると
思います。その中にServletInputStreamがあるか確認
してみてください。
また、Tomcatはどのように起動していますか?

評価

0

ServletInputStreamは、servlet-api.jarだろう。

評価

0

スレとそれますが、少し調べてみました。

javax.servlet_2.4.0.v200706111738.jarは、
Tomcat実行中にページの動的な追加、変更など
に使われているらしい。
Tomcat自体とは別と考えて、これはとりあえず
無視してください。

評価

0

kj様 $様
servlet-api.jarの中にServletInputStreamはありました。
Tomcatは、Eclipse上のTomcat起動ツールバーより起動をかけています。

評価

0

アップロードはとりあえず無視して、
List list = upload.parseRequest(request);
を通ったら、コンソール上に
【done...】
を表示させるようなミニマムコードを作成しました。
しかし、Eclipseのコンソールには
2008/11/05 16:06:38 org.apache.catalina.core.StandardWrapperValve invoke
致命的: サーブレット UploadServlet のServlet.service()が例外を投げました
が出ました。
念のため、
List list = upload.parseRequest(request);
にブレークポイントを設定して、F6を押下していくと、ApplicationFilterChainクラスのinternalDoFilterEventメソッドで一旦とまり、その後F6を押下し続けると、Http11Processorクラスで、

ソースが見つかりませんでした。
JARファイルtomcat-coyote.jarにソース添付がありません。
下の「ソースの添付」ボタンをクリックすると、ソースを添付できます:

が表示されました。

評価

0

upload.parseRequest(request)じゃなくて、
ServeltInputStream in = request.getInputStream();
としてuploadを使わないでください。

評価

0

List list = upload.parseRequest(request);

ServeltInputStream in = request.getInputStream();

として動かそうとしましたが、
ServeltInputStreamを型に解決できません。
というメッセージが戻ってきました。

なお、package の次の行で、import javax.servlet.*; と宣言しています。

評価

0

いったんimport宣言をすべて削除して、
個別クラスの宣言にしたら、どうなります?

Eclipseなら、補完もしてくれるし、難しくないでしょ。

ところで、そのプロジェクトは、
「Tomcatプロジェクトをつくるメニュー」(うろ覚え)から
始めたものなんですよね。

評価

0

コンパイル(ビルド)はできていますか、それとも、実行時エラーですか?
コンパイルできない場合は、eclipseの参照ライブラリに
servlet-api.jarはあるか確認してください?

評価

0

申し訳ありません。
シンタックスエラーでした。<ServeltInputStreamを型に解決できません
シンタックスエラーを取り除いたら、ミニマムコードが通りました。

不良社員様
今回のファイルアップロードは、「Javaプロジェクト」より、新規に作りました。

ありがとうございました。

評価

0

コンパイルが通ったということですか、実行できたと
いうことですか?

評価

0

言葉足らずで申し訳ありません。
ミニマムコードが実行でき、コンソール上に【done...】を表示させることができました。

ということです。

評価

0

そしたら、ServletInputStreamの行をコメントアウト
して、uploadの処理を書いてみてください。

評価

0

今まで、コンパイラを通らなかったの?
よくわからん・・・。

評価

0

うーん、ServletInputStreamの行をコメントアウトしてuploadの処理を書いてみたんですが、

2008/11/05 18:23:15 org.apache.catalina.core.StandardWrapperValve invoke
致命的: サーブレット UploadServlet のServlet.service()が例外を投げました
java.lang.ClassNotFoundException: javax.servlet.ServletInputStream
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)

で戻ります。

評価

0

うーん。元のエラーに戻らないのか。

追加情報として以下のことをやってみてください。

・servlet-api.jarとcatalina.jarを検索し、これらの
配置場所を教えてください。複数の場合は全て教えて
ください。

・環境変数クラスパスの内容。

・Javaプロジェクトでの作業手順。

また、eclipseからではなくてTomcatを単体で実行して
logを確認してみるのもいいかもしれない。

評価

0

書き忘れた。
ついでに、eclipseの再起動もやってみてください。

評価

0

本当に動作するか試しにやってみました。

・Tomcat 6.0
・commons-fileupload-1.2.1
・commons-io-1.4 

で、手順どおりにやってみたら、動作したよ。

評価

0

いろいろやってみたら、同様のエラーが発生した。

そこで、確認するけどNoClassDefFoundErrorと
FileNotFoundExceptionの両方が表示されているん
だよね?(エラーメッセージが変わったかと思っていた
けど最初から同じなんだよね。)
エラー内容が同じなら、2008-11-05 19:21と
2008-11-05 19:24の私の発言は無視してください。

<再現方法>
$さんの2008-11-05 13:16の発言を参考にして
%java_home%\jre\lib\ext内にfileuploadのjarを
配置する。

そこで確認するがeclipseのビルドパスにfileupload
のjarをどのように設定したのか教えてください。

評価

0

書き忘れたので補足します。

エラー原因は、Tomcatが実行時にWEB-INF\lib内のfileuploadのjarを参照していないことが考えられる。

よって、PC上にfileuploadのjarが複数存在していないか確認することを勧めます。複数存在する場合は、WEB-INF\lib以外を削除する。(Tomcatが参照する可能性がある場所だけでもいいが、面倒なのでPC全体を検索してみてください。)

ここからは、予測です。
WEB=INF\lib内にしかfileuploadのjarがなくてエラーが発生する場合は、環境変数CLASSPATHにfileuploadのjarを設定しているからエラーとなっている。

評価

0

>WEB=INF\lib内にしかfileuploadのjarがなくてエラーが発生する場合は、環境変数CLASSPATHにfileuploadのjarを設定しているからエラーとなっている。

これは嘘でした。Tomcat5.Xと同様に環境変数CLASSPATH
は無視されるみたい。

評価

0

>そこで確認するがeclipseのビルドパスにfileupload
>のjarをどのように設定したのか教えてください。
fileuploadのjar専用のクラスパス変数は作成していません。
ただ、TOMCAT_FILEという変数名で、"Tomcatがインストールされているフォルダ\lib"のフルパスが用意されています。

評価

0

>TOMCAT_FILEという変数名で、"Tomcatがインストールされているフォルダ\lib"のフルパスが用意されています。
tomcat/libからはfileuploadは削除したんじゃなかったの?

評価

0

>tomcat/libからはfileuploadは削除したんじゃなかったの?
削除はしております。

評価

0

eclipseでコンパイル(ビルド)してるんですよね?

eclipseのパッケージエクスプローラのプロジェクト以下ににJREシステムライブラリと参照ライブラリがありますよね。
そのどちらにfileuploadのjarは含まれていますか?

評価

0

>eclipseのパッケージエクスプローラのプロジェクト以下ににJREシステムライブラリと参照ライブラリがありますよね。
>そのどちらにfileuploadのjarは含まれていますか?
JREシステムライブラリはありましたが、参照ライブラリ、という名前ではありませんでした。
参照ライブラリとは、WebAppライブラリのことでしょうか。
JREシステムライブラリーにはありませんでしたが、WebAppライブラリにはfileuploadのjarはありました。

評価

0

Tomcatプロジェクトじゃないのね。

http://www.kakic.net/cgi/mt/mt-search.cgi?IncludeBlogs=3&search=%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA

の「ライブラリの追加がうまくいかない時」を参照
してみてください。

評価

0

情報を小出しにしすぎてて、ディレクトリ構成が分からなくなっている。
スレが長くなるのは、1つ1つの書き込みが簡単すぎて、必要な情報がなかなかまとまらないためだ。
Tomcatプロジェクトなら、

プロジェクト

の直下に動かそうとしているJSPがあり、

プロジェクト/WEB-INF/lib

にfileupload.jarがあればいい。
他にどこにもないか、Explorerの検索ででも、ちゃんと探したのか?
目で追っているだけだと見落とし勝ち。

評価

0

あ、いかん。Tomcatプロジェクトじゃないのか。
まあ、いずれにしても構成は同じになるはずなんだけど。

評価

0

「ライブラリの追加がうまくいかないとき」を参照して、やっとファイルアップロードの確認が取れました。

$様、不良社員様、kj様。本当にありがとうございました。

評価

0

右クリックしてRefreshで、ファイルシステム(Explorer)と同期が取れるはずなんだけどな。

評価

0

>右クリックしてRefreshで、ファイルシステム(Explorer)と同期が取れるはずなんだけどな。
その方法は知りませんでした。
ありがとうございます。

評価

0

単に同期がとれてないだけだったの?
それとも、「ライブラリの追加がうまくいかないとき」に書いてあるクラスローダの親子関係が原因だったの?

何をしたら、うまくいったか書いてください。

評価

0

プロジェクトのプロパティ内、Javaのビルドパスで、WebAppライブラリーの順序を上位に持っていったら動作確認が取れました。

評価

0

ネットが見れない状態で遅くなりました。

動作確認ができて、よかったですね。

しかし、なぜJavaのビルドパスで順序を上位に持っていくとうまくいったのか私にはわかりません。
原因を知りたいです。(いろいろと予想はできますが・・・。)

以下は、暇だったので私がやってみたことです。

なにがしさんの書き込み内容から、WTPを使い動的Webプロジェクトを作成していると思って、動的Webプロジェクトを作成し、ファイルアップロードの確認をしてみました。
ビルドパスのWebAppライブラリにfileuploadのjarは含まれるようにして、順序を一番下位において動作確認してみました。
結果は、正常に動作しました。

よって、なにがしさんとは何らかの違いがあるはずだと思われます。しかし、確かめようがないためこの時点でやめました。


私の2008-11-06 06:02の書き込みの補足もしておきます。
Tomcat6にCLASSPATHを認識させる方法はちゃんとあります。(デフォルトではCLASSPATHほ無視されるということです。)

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。