URL url = new URL(strURL);
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
OutputStream os = urlc.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(compressedCallInfo);
os.close();
// Servlet decompresses object, processes and recompresses result
InputStream in = urlc.getInputStream();
ObjectInputStream ois;
try {
ois = new ObjectInputStream(in);
} catch(java.io.StreamCorruptedException e){ ...}
The stacktrace looks like binary soup:
sr java.io.StreamCorruptedException|????9??? xr
?java.io.ObjectStreamExceptiond??k?9??? xr ?java.i
o.IOExceptionl?sde%??? xr ?java.lang.Exception???>?;??? xr
?java.lang.Throwabl
detailMessaget ?Ljava/lang/String;xpt 0InputStream does not contain a
serialized
object
This worked on a bog-standard webserver running as a CGI servlet. Have
recently moved it to Tomcat and that's when the problem started occurring.
Your views would be appreciated.
Regs, James
James Keeley <jke...@monsanto.com> wrote:
> Here's the code I'm using trying to read back an Object from a Servlet:
> URL url = new URL(strURL);
> URLConnection urlc = url.openConnection();
> urlc.setDoOutput(true);
> OutputStream os = urlc.getOutputStream();
> ObjectOutputStream oos = new ObjectOutputStream(os);
> oos.writeObject(compressedCallInfo);
You miss
oos.flush();
> os.close();
or use
oos.close();
in the first place.
Christian
Sorry Christian, forgot to copy and past that line. Yes, oos.close is
there.
Jon, if you have a moment, do you see any glaring errors?
> Jon, if you have a moment, do you see any glaring errors?
I'd close oos rather than os, although I wouldn't have thought that
should account for the bizarre stack trace.
What happens if you write a small *application* (with the appropriate
classpath etc) which just reads in the file that has been written?
--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Is it where he suggested it should be, i.e. before (or instead of)
os.close()?
/gordon
--
[ do not send me private copies of your followups ]
g o r d o n . b e a t o n @ e r i c s s o n . c o m
I'm not Jon, but I can say some things:
James Keeley wrote ...
> > URL url = new URL(strURL);
> > URLConnection urlc = url.openConnection();
> > urlc.setDoOutput(true);
> > OutputStream os = urlc.getOutputStream();
> > ObjectOutputStream oos = new ObjectOutputStream(os);
> > oos.writeObject(compressedCallInfo);
> > os.close();
There are some improvements in form that can be made here. For example:
- Generally, you should close the outermost containing stream instance,
and let that close the internal streams. So, change os.close() to
oos.close() instead.
- Put your close statement in a finally block, as in:
OutputStream os = null;
ObjectOutputStream oos = null;
try
{
... other stuff
}
finally
{
if (oos != null) oos.close();
else if (os != null) os.close();
}
> > InputStream in = urlc.getInputStream();
> > ObjectInputStream ois;
> >
> > try {
> > ois = new ObjectInputStream(in);
> > } catch(java.io.StreamCorruptedException e){ ...}
This looks okay... again aside from not properly closing the stream, but
it should be okay so far.
> > The stacktrace looks like binary soup:
> >
> > sr java.io.StreamCorruptedException|????9??? xr
> > ?java.io.ObjectStreamExceptiond??k?9??? xr ?java.i
> > o.IOExceptionl?sde%??? xr ?java.lang.Exception???>?;??? xr
> > ?java.lang.Throwabl
> > detailMessaget ?Ljava/lang/String;xpt 0InputStream does not contain a
> > serialized
> > object
This is the *complete* stack trace? If you say e.printStackTrace() in
the catch block above, this is what you see?
> > This worked on a bog-standard webserver running as a CGI servlet. Have
> > recently moved it to Tomcat and that's when the problem started occurring.
Perhaps you should post your servlet code. I see nothing wrong on the
client that should have this effect.
Chris Smith
I've tried writing an object to a file (rather than via a URLConnection) on
my PC and ftp'ing it across to the server (where the servlet resides) and
reading it back on the server and the data retains it's integrity.
I've tried both:
oos.flush();
os.close();
oos.close();
os.close();
> I've tried writing an object to a file (rather than via a URLConnection) on
> my PC and ftp'ing it across to the server (where the servlet resides) and
> reading it back on the server and the data retains it's integrity.
Okay - the next step is to grab the bytes *over* a URL connection and
then write them to a file again, then see whether those two files are
the same.
> Perhaps you should post your servlet code. I see nothing wrong on the
> client that should have this effect.
>
> Chris Smith
Hi Chris,
Thanks for the form tips.
This is the full stack trace:
sr java.io.StreamCorruptedException|????9??? xr
?java.io.ObjectStreamExceptiond??k?9??? xr ?java.i
o.IOExceptionl?sde%??? xr ?java.lang.Exception???>?;??? xr
?java.lang.Throwabl
detailMessaget ?Ljava/lang/String;xpt 0InputStream does not contain a
serialized
object
java.io.StreamCorruptedException: Caught EOFException while reading the
stream header
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
...and the pertinent servlet code:
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
ServletOutputStream sos = res.getOutputStream();
InputStream inputStream = req.getInputStream();
servicePostRequest(inputStream, sos, getJdbcConnectString());
}
public static void servicePostRequest(InputStream inputStream, OutputStream
outputStream, String jdbcConnectString)
throws IOException
{
try{
//read in the compressed query object
ObjectInputStream ois = new ObjectInputStream(inputStream);
CompressedData compressedCallInfo = (CompressedData)ois.readObject();
//uncompress the query object
Compressor compressor = new Compressor();
callInfo = uncompressForHttp(compressedCallInfo, compressor);
//execute query
dbObj = makeDBObj(callInfo.userName_, callInfo.password_,
callInfo.ppVer_, jdbcConnectString);
dbObj.execProc(callInfo.procName_, callInfo.args_);
//compress result of query
CompressedData compressedResultSets =
compressForHttp(dbObj.getResultSets(), compressor);
//serialise the response and send back to the requesting program
ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject(compressedResultSets);
oos.close();
}
//serialise these exceptions and return them to the requesting program
catch(Exception e) {} ...
Ah - is this how you managed to get that dodgy exception stack trace? If
serialisation is failing, it seems odd to rely on it to get accurate
tracing for the problem. If you can echo the exceptions *locally*
instead, that would help.
That is something. The response from the server is getting cut short.
Some things to try:
1. Try calling setDoInput(true) on the client side... perhaps the client
is not waiting for a response.
2. You are closing the ServletOutputStream in your server-side
implementation. I've found this to cause problems in a few cases... try
using flush() instead of close(), and letting the servlet container close
the stream.
Chris Smith
That output was from the client side...I was just truncating the verbosity
of the Exception code in the servlet as it's not getting thrown there.
Ah, right. Can you see how to implement my previous suggestion, ie to
save the file at the client side and compare it with a file created at
the server side of the same object?
Yes.
Since I have an Object being written across the URLConnection, I'm checking
that I can read that same Object at server side.