General J2EE: Uplaoding a file from Web Tier of a J2EE application
- Posted by: sourav mazumder
- Posted on: January 02 2004 05:46 EST
I have a J2EE application running on WebLogic 8.1 on Solaris 8.
The application needs to provide functionality of File Upload. For the file upload purpose we are using Multipart Upload component of struts 1.0.2.
At the implementtaion level, after getting the file object at the web tier (i.e. in action class) we are creating a byte array and sending this byte array through EJB in the ejb tier of the application. From the EJB the byte array goes to a business object (Plain Java object) which does File IO to upload the byte array as a file in the target file server.
This solution works fine when we test it for file upload in an isolated way. However, when we try to upload multiple files (say 5 to 6 in number and of size approx 2 MB) concurrently, the server crashes.
The concurrent upload, however, works fine when we directly try to upload the file from the action class itself.
Based on the above observation I have following doubts -
1. Is it a good approach to upload file to the file server from the Web Tier itself, instead of doing it from EJB Tier.
2. What could be the reason for server crashing when we are trying to upload multiple files from the EJB tier concurrently ? And why is not happening if we do the upload from the action class ?
Any information/pointer in this regard will be highly appreciated.
- Uplaoding a file from Web Tier of a J2EE application by Sean Sullivan on January 02 2004 17:56 EST
- Another approach by Mircea Crisan on January 13 2004 10:46 EST
- Uplaoding a file from Web Tier of a J2EE application by J MacDiarmuida on July 08 2004 23:22 EDT
2. What could be the reason for server crashing when we are
> trying to upload multiple files from the EJB tier concurrently ?
> And why is not happening if we do the upload from the action class ?
The server is crashing?
Please check your log files.
Is there an exception?
Do you have a stack trace?
Loading in memory the upload content may cause memory problemes, especially when the uploads get large. Instead of passing the byte array to the other layers (EJBs) I suggest passing an InputStream. I suppose that the stream will eventually arrive at some data access layer where it will be inserted in a database BLOB. I have applied this when uploading some mp3s from a browser to an application server that in turn inserts the content in the database. Don't forget (as I did ;-) ) to close the stream and delete the form file after you're done.
Best regards, Mircea
I have to add some renmarks about mu prviuos post.
The InputStream approach works only when the web layer and the bussiness layer (EJB) are in the same JVM. If you plan to have more JVMs then the problem becmes more complicated. here are some approaches
1. pass an URL pointing to the content file. The problem is that the location of the uploaded files have to be accessible through the network. You also have to given net and io permissions to the EJBs
2. send small size byte arrays that are apended to the database BLOB. This implies a more database access code.
Best regards, Mircea
I too have had this issue with a similar architecture. Please see http://www.theserverside.com/discussions/thread.tss?thread_id=27083
In my case the server does not crash (WLS 704 on Solaris). What happens is the WLS run queue gets out of control and WLS spends time processing these as a priority. Therefore the users have to wait say 45+mins for it to recover. Mind you I had 4 developers uploading and downloading 2M+ files at the same time for about 15 mins in the test environment.
Bottom line, it seems to me that passing large documents around in memory and converting these persistent objects into DVOs for passing to the web-tier and vice versa can have disastrous affects on the app server (memory uage, garbage collection, and response times (processing/job queue)). If anyone thinks otherwise let me know.
I am in the process of reviewing this with the group in order to get around this issue. One proposal is to stream directly from/to db from from the Struts ActionClass as you mentioned. I would like to know if you went forward with this approach and if so did it fix your problem.