getting null, in object transfer.

  • Thread starter prabodhachyutha
  • Start date
P

prabodhachyutha

Hi,

I got a problem when sending the data from the serverside and getting
it back in the client side. We are not getting the object(here it is
DataTransferObject which is Serializable) as null in the client side.

I am putting the serverside code.

public void sendDataObjectToClient(
HttpServletResponse res,
DataTransferObject obj,
String accepts) {

ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ServletOutputStream sos = null;
boolean didCompress = false;
try {
sos = res.getOutputStream();
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
oos.close();
byte[] bytes = bos.toByteArray();
int origLength = bytes.length;
if ((bytes.length > 1024 * 2)
&& accepts != null
&& accepts.indexOf("gzip") >= 0) { // large response, compress it.
ByteArrayOutputStream zbaos = new ByteArrayOutputStream();
GZIPOutputStream zo = new GZIPOutputStream(zbaos);
zo.write(bytes);
zo.flush();
zo.close();
bytes = zbaos.toByteArray();
log.debug(
"Writing compressed response, orig="
+ origLength
+ " new length="
+ bytes.length);
didCompress = true;
} else {
log.debug("Writing response, length=" + bytes.length);
}
res.setContentType("application/x-java-serialized-object");
res.setContentLength(bytes.length);
if (didCompress == true) {
res.setHeader("Content-encoding", "gzip");
}
try {
sos.write(bytes);
sos.flush();
} catch (IOException ioerror) {
log.info("I/O Error to Client " + ioerror.toString());
}
} catch (Exception e) {
log.error("Unexpected error sending data to client", e);
} finally {
if (sos != null) {
try {
sos.close();
} catch (Exception ignored) {
}
}
}
}

We are using java 1.3 at serverside and 1.4 at the clientside.

And also this problem is not occuring continuously, sometimes we are
getting the object and some times its null. What could be the reason
behind this.

This is very critical for us, any possible solution would be really
helpful for us.

Thanks in advance.
 
R

Roedy Green

We are using java 1.3 at serverside and 1.4 at the clientside.

you can't do that necessarily. Sun's Objects in general are not
guaranteed to be compatible between Java versions.

You might try generating the stream with Java 1.3 and with 1.4 and
comparing. Recall that all classes transported must have identical
serialUIDs and identical non-transient fields.
 
E

Esmond Pitt

Roedy said:
Recall that all classes transported must have identical
... non-transient fields.

This is not so: see the Serialization Specification, section on Versioning.
 
P

prabodhachyutha

This problem is not occuring always, only few times the obeject(in
transfer) is becoming null. Did anybody faced this type of issue
earliear?

Please help us.
 
M

Matt Humphrey

| Hi,
|
| I got a problem when sending the data from the serverside and getting
| it back in the client side. We are not getting the object(here it is
| DataTransferObject which is Serializable) as null in the client side.
|
| I am putting the serverside code.
|
| public void sendDataObjectToClient(
| HttpServletResponse res,
| DataTransferObject obj,
| String accepts) {
|
| ByteArrayOutputStream bos = null;
| ObjectOutputStream oos = null;
| ServletOutputStream sos = null;
| boolean didCompress = false;
| try {
| sos = res.getOutputStream();
| bos = new ByteArrayOutputStream();
| oos = new ObjectOutputStream(bos);
| oos.writeObject(obj);
| oos.flush();
| oos.close();
| byte[] bytes = bos.toByteArray();
| int origLength = bytes.length;
| if ((bytes.length > 1024 * 2)
| && accepts != null
| && accepts.indexOf("gzip") >= 0) { // large response, compress it.
| ByteArrayOutputStream zbaos = new ByteArrayOutputStream();
| GZIPOutputStream zo = new GZIPOutputStream(zbaos);
| zo.write(bytes);
| zo.flush();
| zo.close();
| bytes = zbaos.toByteArray();
| log.debug(
| "Writing compressed response, orig="
| + origLength
| + " new length="
| + bytes.length);
| didCompress = true;
| } else {
| log.debug("Writing response, length=" + bytes.length);
| }
| res.setContentType("application/x-java-serialized-object");
| res.setContentLength(bytes.length);
| if (didCompress == true) {
| res.setHeader("Content-encoding", "gzip");
| }
| try {
| sos.write(bytes);
| sos.flush();
| } catch (IOException ioerror) {
| log.info("I/O Error to Client " + ioerror.toString());
| }
| } catch (Exception e) {
| log.error("Unexpected error sending data to client", e);
| } finally {
| if (sos != null) {
| try {
| sos.close();
| } catch (Exception ignored) {
| }
| }
| }
| }
|

Your writing code looks reasonable, other than the empty exception handler.
Are you sure that every object that is reachable from your
DataTransferObject is also serializable every time you write data? What
does your reading code look like? There are ways to miscode reading that
will cause the problem (e.g. expecting the data to arrive in a single
packet.)

Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
R

Roedy Green

This is not so: see the Serialization Specification, section on Versioning.

In practice it is. Try writing some code. It is not nearly as robust
as you would suspect from the docs.
 
E

Esmond Pitt

Roedy said:
In practice it is. Try writing some code. It is not nearly as robust
as you would suspect from the docs.

I've written lots of serialization code, thanks, and I haven't
encountered any problems whatsoever when sticking to the versioning
constraints specified.

What specific problems have you encountered?
 
E

Esmond Pitt

I got a problem when sending the data from the serverside and getting
it back in the client side. We are not getting the object(here it is
DataTransferObject which is Serializable) as null in the client side.

If you are getting a null, *and no exceptions*, at the client, and no
exceptions at the server, it can only mean that the object reference was
null when you serialized it.
 
P

prabodhachyutha

All,

Thanks for giving some suggestions, now we clearly got the information
on where is the actual problem is.

We are using swing client, where in we are calling the server using
the threads. Here the problem is 1. Two threads are calling the
server
2. Server is sending 2 objects as response(same type)
3. but both threads taking the same object (which is returned last) as
the input(not always)

We are not able to understand, Why this is happening?

What is the best way to resolve this.
 
R

Roedy Green

I've written lots of serialization code, thanks, and I haven't
encountered any problems whatsoever when sticking to the versioning
constraints specified.

But you are not a novice. A novice will inevitably trip. So I
suggest for a novice you ensure all classes and serial IUDs are
identical read and write.
 
E

Esmond Pitt

Roedy said:
But you are not a novice. A novice will inevitably trip. So I
suggest for a novice you ensure all classes and serial IUDs are
identical read and write.

You're misquoting. Clearly I was commenting on your statement that 'all
classes transported must have identical ... non-transient fields' and
your subsequent apparent claim that the Versioning provisions of
Serialization aren't 'nearly as robust as you would suspect from the
docs'. If that's not what you're saying, we agree. If it is what you're
saying, I'd like some chapter and verse as to exactly what doesn't work
and where it is acknowledged in the Bug Parade.
 
N

Nigel Wade

All,

Thanks for giving some suggestions, now we clearly got the information
on where is the actual problem is.

We are using swing client, where in we are calling the server using
the threads. Here the problem is 1. Two threads are calling the
server
2. Server is sending 2 objects as response(same type)
3. but both threads taking the same object (which is returned last) as
the input(not always)

We are not able to understand, Why this is happening?

What is the best way to resolve this.

Given that brief description my first assessment would be that you have a thread
symchronization problem in your servlet. It sounds like you are returning an
object which is shared between the multiple threads within the servlet (each
invocation of a servlet is likely to be on a different thread). Look at where
the object you are returning is defined. Is it within the service method? If
not then it is most likely shared between threads and must be synchronized.

Unfortunately it's impossible to be more specific without more specific details.
 
P

prabodhachyutha

Thanks for all your support. We solved the problem. Problem is badly
written client side code. For the every request, client is invoking a
thread. In run() method it is loading the DTO(object) to the same
class's field.

public void run() {
try {
dto = getData(obj);
} catch (Exception e) {}
}

Here getData() method is processing the server response and returning
it. But two threads are referring same "dto". (Note: dto is not method
local, it is class variable).

We solved this by threads sychornization.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top