- - PR -
Struts のファイルアップロードでNotSerializableException が発生
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2004-11-11 15:36
こんにちは。kenと申します。
現在 Servlet + JSP + Struts を使用してシステム開発をしています。 Struts のファイルアップロード機能を使用しているのですが 使用している AP サーバー のログに以下のようなエラーメッセージが 出力されます。 例外: java.io.NotSerializableException: org.apache.commons.fileupload.DeferredFileOutputStream AP サーバーは複数台設置してロードバランサーで処理を振り分けています。 この org.apache.commons.fileupload.DeferredFileOutputStream は commons-fileupload.jar に含まれていました。 java.io.Serializable を implements していないためだと思うのですが このような場合どのようにすればよいのでしょうか? 自身で定義している JavaBeans などには Serializable を implements しています。 ファイルアップロードは Action クラスで以下のように実装しています。 import org.apache.struts.upload.FormFile; import org.apache.struts.validator.DynaValidatorForm; public class xxxxxAction extends Action { private static final int READ_BUFFER_SIZE = 8192; public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { DynaValidatorForm theForm = (DynaValidatorForm) form; FormFile formFile = (FormFile) theForm.get(BeanConst.UPLOAD); InputStream stream = formFile.getInputStream(); byte[] buffer = new byte[READ_BUFFER_SIZE]; stream.read(buffer, 0, READ_BUFFER_SIZE) 環境 Redhat Linux AS 2.1 IBM JDK 1.4.1 Struts 1.1 IBM WebSphere 5.1 どなたかご存知のかたがおられましたらよろしくお願いいたします。 |
|
投稿日時: 2004-11-11 15:44
どういった文脈で NotSerializableException が発生しているのでしょうか?
負荷分散しているとのことなのでセッションの属性をレプリケートしている際に発生しているのでしょうか。 DeferredFileOutputStream ってクラスを使ったことはありませんがクラスタ化するのであればもちろんセッションにセットする属性は Serializable である必要がありますね。 OutputStream のサブクラスを Serializable に実装するのは難しいと思いますので、セッションにセットしないようにしてはいかがでしょうか? #それともセッションにセットしていないのに発生している? |
|
投稿日時: 2004-11-11 17:09
ご回答ありがとうございます。
DeferredFileOutputStream クラスはプログラム中では使用していません。 org.apache.struts.upload.FormFile の内部で Jakarta Commons の commons-fileupload.jar 内にある DeferredFileOutputStream クラスを使用しているのだと思います。 ActionForm を struts-config.xml 内で以下のように記述しています。 <form-bean name="UserCsvUploadForm" type="org.apache.struts.validator.DynaValidatorForm"> <form-property name="viewId" type="java.lang.String" /> <form-property name="preViewId" type="java.lang.String" /> <form-property name="uploadFile" type="java.lang.String" /> <form-property name="upload" type="org.apache.struts.upload.FormFile" /> </form-bean> ActionForm に org.apache.struts.upload.FormFile を セットしていますので HTTP セッションにセットされるのでしょうね。 NotSerializableException がログに出力されているのですが処理自体は正常に行われます。 また AP サーバが1台の場合は NotSerializableException は出力されません。 試しに Jakarta Commons の DeferredFileOutputStream クラス で Serializable を implements するように修正したのですが 今度はその中で使用されている ByteArrayOutputStream で NotSerializableException が発生してしまいます。 これは java.io パッケージに属するクラスですので触っていません。 分散セッションの環境ではこのようなコーディングではダメなのでしょうか? 以下はログに出力されているメッセージです。 [04/11/08 10:37:44:643 JST] 312d95d8 DRSCacheApp E DRSW0008E: 例外: java.io.NotSerializableException: org.apache.commons.fileupload.DeferredFileOutputStream at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java(Inlined Compiled Code)) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java(Inlined Compiled Code)) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java(Inlined Compiled Code)) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java(Inlined Compiled Code)) at java.util.ArrayList.writeObject(ArrayList.java(Compiled Code)) at sun.reflect.GeneratedMethodAccessor995.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code)) at java.lang.reflect.Method.invoke(Method.java(Compiled Code)) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java(Compiled Code)) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java(Compiled Code)) at java.util.HashMap.writeObject(HashMap.java(Compiled Code)) at sun.reflect.GeneratedMethodAccessor83.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code)) at java.lang.reflect.Method.invoke(Method.java(Compiled Code)) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java(Compiled Code)) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java(Inlined Compiled Code)) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code)) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java(Compiled Code)) at com.ibm.ws.drs.DRSUtils.getBytes(DRSUtils.java(Compiled Code)) at com.ibm.ws.drs.DRSCacheApp.getBytes(DRSCacheApp.java(Inlined Compiled Code)) at com.ibm.ws.webcontainer.httpsession.DRSHttpSessCache.setJCMPropObj(DRSHttpSessCache.java(Compiled Code)) at com.ibm.ws.drs.DRSAPI.updateEntryProp(DRSAPI.java(Compiled Code)) at com.ibm.ws.drs.DRSCacheApp.updateEntryProp(DRSCacheApp.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.DRSBackedHashtable.handlePropertyHits(DRSBackedHashtable.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.DRSBackedHashtable.persistSession(DRSBackedHashtable.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.BackedHashtable.ejbStore(BackedHashtable.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.BackedHashtable.storeSession(BackedHashtable.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.BackedHashtable.put(BackedHashtable.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.DatabaseSessionContext.sync(DatabaseSessionContext.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.SessionData.releaseSession(SessionData.java(Compiled Code)) at com.ibm.ws.webcontainer.httpsession.SessionContext.sessionPostInvoke(SessionContext.java(Compiled Code)) at com.ibm.ws.webcontainer.webapp.WebAppDispatcherContext.sessionPostInvoke(WebAppDispatcherContext.java(Inlined Compiled Code)) at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java(Compiled Code)) at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java(Compiled Code)) at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1069) at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:455) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:279) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525) at javax.servlet.http.HttpServlet.service(HttpServlet.java(Compiled Code)) at javax.servlet.http.HttpServlet.service(HttpServlet.java(Compiled Code)) at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java(Compiled Code)) at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java(Compiled Code)) at com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java(Compiled Code)) at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java(Inlined Compiled Code)) at com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java(Compiled Code)) at com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java(Compiled Code)) at com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java(Inlined Compiled Code)) at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java(Compiled Code)) at jp.co.calm.sec.authserver.filter.AuthorityFilter.doFilter(Unknown Source) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java(Compiled Code)) at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java(Compiled Code)) at jp.co.calm.sec.authserver.filter.SetCharacterEncodingFilter.doFilter(Unknown Source) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java(Compiled Code)) at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java(Compiled Code)) at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java(Compiled Code)) at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java(Compiled Code)) at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java(Compiled Code)) at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java(Compiled Code)) at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java(Compiled Code)) at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java(Compiled Code)) at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java(Compiled Code)) at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java(Compiled Code)) at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java(Compiled Code)) at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java(Compiled Code)) at com.ibm.ws.http.HttpConnection.run(HttpConnection.java(Compiled Code)) at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code)) |
|
投稿日時: 2004-11-11 17:15
ローカルのディスクに書き込んだファイルを参照しているオブジェクトをレプリケートしても他のサーバでは役に立ちませんから、FormFile を含む FormBean をセッションに放り込むべきではありませんね。
または、フェールオーバを必要としないのであればクラスタリングを行わず、セッションIDでロード場欄寝具させればOkです。レプリケートさせなければシリアライズ-デシリアライズは行われないと思いますので。 |
|
投稿日時: 2004-11-26 13:52
ご返事が遅くなり申し訳ありませんでした。
現象が発生する環境で試すことができました。 以下そのご報告です。 struts-config.xmlファイルのアクションクラスの定義の スコープを session から request にすることで解消されました。 <action path="/xxxx/xxxx" type="xx.xx.xx.xxxxxx" name="xxxxxx" validate="false" scope="session"> ↓ scope="request"> ご教示いただきましてありがとうございました。 |
1