Hello,
I'm using JAX-WS 2.1
( <project name="JAX-WS 2.1.1 RC1 RI On Sun Java System App Server
8.1/8.2/9.0/9.0 U1, GF v1, GF v2 M1, M2" default="help" basedir=".">)
and have lot's of trouble uploading large (>2GB, but already stalls at
300 MB) files:
I receive a OutOfMemory-Exception:
Here's my server and client code, my analysis of the problem follows:
Client Code:
try
{
PlayoutBackendService service = new PlayoutBackendService();
//
PlayoutServer pServer = service.getPlayoutServerPort();
SOAPBinding
binding=(SOAPBinding)((BindingProvider)pServer).getBinding();
//enable chunking - the problem is not better without chunking !
((BindingProvider)pServer).getRequestContext().put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE,8196);
System.out.println("Is MTOM enabled? "+binding.isMTOMEnabled());
if (pServer==null)
{
System.out.println("TEST FAILURE: Couldnt get port!");
System.exit(-1);
}
System.out.println("befor Upload");
pServer.uploadTest(new MyDataHandler(new
FileDataSource("name_of_large_file"))); //MyDataHandler is just a
wrapper with every method overwritten with
system.out.println([methodname]) super(...) to see what's going on
during file transfer over the wire - a regular DataHandler yields the
same results
System.out.println("after upload");
}
catch (Exception ex)
{
System.out.println("Error!");
ex.printStackTrace();
}
System.out.println("Done!");
System.exit(3);
Here is my Server code:
@WebMethod
public boolean uploadTest(@WebParam(name="dHandler")
@XmlAttachmentRef()
DataHandler data)
{
try
{
InputStream is = data.getInputStream();
// Open a file output stream to recieve the data.
FileOutputStream fos = new FileOutputStream(new File("c:/upload.txt"));
// Create a 2k buffer to use by default.
byte[] buffer = new byte[1024];
// Determine the number of bytes available.
int available = is.available();
// Loop until no more bytes are avialable.
while (available > 0)
{
// Resize the buffer as needed.
if (available < buffer.length)
{
buffer = new byte[available];
}
// Read the data into the buffer.
is.read(buffer);
// Write the data to the file.
fos.write(buffer);
// Get the number of bytes available.
available = is.available();
}
fos.close();
System.out.println("Transfer done.");
}
catch (Exception ex)
{
System.out.println("Exce: " + ex.toString());
}
return false;
}
My Analysis: everything runs fine, Fiber.__doRun(Tube) is executed,
HttpTransportPipe.process(Packet) is called,
SwACodec(MimeCodec).encode is called - here the Problems start, as far
as I think: the attachment stream should be send without encoding, right?
At least, SwaCodec calls DataHandlerAttachment.writeTo, here
DataHandlerAttachment.asByteArray is called, (for obvious reasons)
resulting in Out of Memory....
Please, tell me, am I doing something wrong or is the implementation not
perfect? I thought, the datahandler has to stream has bytes directly out
to the http connection, thus that only a limited amount of bytes has to
be kept in memory and the complete stream never has to be read.
Thanks a lot!
Christian