Thanks Andrea,

That gives me a hope. I would try to go in that direction and contact
you if I need any help.

-Yuva



-----Original Message-----
From: Andreas Veithen [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, March 12, 2008 3:23 PM
To: axis-user@ws.apache.org
Subject: Re: Question regarding attachments with Axis and DataHandler

Yuva,

I didn't have the time yesterday to elaborate on a possible solution  
to your problem. I implemented a solution for a similar problem in JAX- 
WS some time ago, but the approach will be the same in Axis2.

What you need to do is to implement your own  
javax.activation.DataSource. The difficulty is that you can't just  
call Blob#getBinaryStream in your code, wrap it in a DataSource object  
and return it to Axis. This won't work because when Axis starts to  
read the input stream, the JDBC connection that was used to get the  
Blob has already been closed (at least if you handle your database  
connections properly with javax.sql.DataSource). The first part of the  
solution is to get the database connection, execute the query and call  
Blob#getBinaryStream inside your DataSource#getInputStream method. The  
second part of the solution is to make sure that when Axis calls  
InputStream#close, you also close the database connection. Therefore,  
in your DataSource#getInputStream method you can't just return the  
input stream from Blob#getBinaryStream, but you need to wrap it to  
intercept the call to the close method (see the "Proxy" design pattern).

I would do it like that, but it requires some coding skills. There are  
two other approaches I see:

* Write the blob to a temporary file, but this is much less efficient.  
Also, instead of the problem with database connections, you will have  
to take care to clean up the temporary files.
* Execute the query in your code, call Blob#getBinaryStream and wrap  
it in a DataSource object, but without closing the database connection  
at that moment. You will then need to retake control to close the  
connection after Axis has processed the response, by using a servlet  
filter or maybe an Axis handler. This solution would be conceptually  
similar to Spring/Hibernate's OpenSessionInViewFilter, but is more  
complicated to implement.

Regards,

Andreas


On 12 Mar 2008, at 18:56, Chandolu, Yuva wrote:

> Is there a work around/any other solution for this then? If
> ByteArrayDataSource reads whole file into memory my service would run
> out of memory if lots of client access the service at the same time.
>
>
>
> -----Original Message-----
> From: Andreas Veithen [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, March 11, 2008 5:41 PM
> To: axis-user@ws.apache.org
> Subject: Re: Question regarding attachments with Axis and DataHandler
>
> Yuva,
>
> The implementation of the ByteArrayDataSource constructor you are
> using looks as follows:
>
> public ByteArrayDataSource(InputStream is, String type) throws
> IOException {
>     ByteArrayOutputStream os = new ByteArrayOutputStream();
>     byte[] buf = new byte[8192];
>     int len;
>     while ((len = is.read(buf)) > 0)
>         os.write(buf, 0, len);
>     this.data = os.toByteArray();
>     this.type = type;
> }
>
> As you can see, it will indeed read the entire Blob into a
> ByteArrayOutputStream and then copy it to a byte array. It is
> therefore not surprising that you run out of memory.
>
> Andreas
>
>
> On 11 Mar 2008, at 21:42, Chandolu, Yuva wrote:
>
>> Hi,
>>
>> I am trying to replace one servlet serving huge files by a
>> webservice. When request comes in, the servlet opens InputStream to
>> the file blob in database, read from the input stream and write to
>> the http output stream. When client starts pulling the data it comes
>> straight from the input stream of the servlet (pure streaming). In
>> which case the Servlet can handle 100s of clients because the
>> Servlet threads are not trying to load the whole file into memory on
>> the server side and just sending down the data when it is read from
>> the client side.
>>
>> Now I am trying to replace the servlet code by a web service. I am
>> using DataHanlder for attachements. We have big files in database
>> (each 10MB or more). When the client call my service
>> downloadfile(fileName) I need to pull it from the database and
>> create a datahandler and return to the client. My concern is what
>> will happen if 100 clients request the all big files (say each 10 MB
>> in size) using downloadFile() service. My question here is how the
>> datahandler works, will it read all the file contents from file blob
>> from database and store in memory before we return it to the client?
>> Looks like it is because my tomcat is running out of memory when I
>> tried 20 client threads in parallel requesting for big files. How
>> can I solve the problem?
>>
>> Following is my code snippet
>>
>> Blob file_blob = rs.getBlob(1);
>> ByteArrayDataSource bds = new
>> ByteArrayDataSource(file_blob.getBinaryStream(), "application/octet-
>> stream");
>> DataHandler data_handler = new DataHandler(bds);
>>
>> return data_handler;
>>
>> Thanks in advance
>> Yuva
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to