This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Distributed Java and the fly likes How to Ensure I'm NOT Passing RMI Objects I don't Mean to Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Distributed Java
Bookmark "How to Ensure I Watch "How to Ensure I New topic
Author

How to Ensure I'm NOT Passing RMI Objects I don't Mean to

Al Johnston
Ranch Hand

Joined: May 02, 2009
Posts: 99

Hi,

I have gotten an RMI server and client to limp along. But, my client is getting a not serialized exception on an object when I try to run it. I am pretty sure this is a problem of my design and hope that someone can enlighten me on how to make sure this problem is solved.

I have several objects that are serializable. They do all my data lookups and store data that will be used over and over again by my app in HashMaps. Then, when a caller asks the server for data, the server passes these data classes to a controller which queries the HashMaps, builds arrays and passes back the arrays. I also want to be able to pass that controller to callers so that they can call other methods without having to ask the server for the controller each time the client wants to do something.

I designed the data classes such that when they are created by the server, they do all their data work and then close the Connection before any client can ask them for their HashMap data. But, while the JVM should have no reference to the Connection at the point that the client asks for data, I'm finding that RMI is still passing down a net.sourceforge.jtds.jdbc.ConnectionJDBC3 object and throwing a non-serializable error when doing so.

Given that I have several methods that may need to query the DB when the app starts, I have a member Connection in each of my classes that need to do this. An example:



I then use the Connection to do my query and have a finally block that closes the connection and sets it to null. Since my data objects are the only objects that have any knowledge of a Connection at all, they must be what RMI is complaining about. If I changed the code from above to the following in all of my data objects, would it then solve the problem if any of my data objects are passed to the constructor of my controller which is subsequently passed to the client?



If that won't solve the problem, can you help me see how to design this so that I can solve the problem?

Thanks,
Al
Edward Harned
Ranch Hand

Joined: Sep 19, 2005
Posts: 291

Where is the RMI code?

Specifically, what classes are you passing. Let's see the code.


Ed's latest article: A Java Parallel Calamity http://coopsoft.com/ar/Calamity2Article.html
Al Johnston
Ranch Hand

Joined: May 02, 2009
Posts: 99

Thanks Edward. I was trying to shorten up my post. Happy to post anything that is needed. I'll abridge the objects to include only the methods that are being called right now, down to an object in the package that I think is giving me the problem...

Deleting all the abridged code I was asked to post.

Edward Harned
Ranch Hand

Joined: Sep 19, 2005
Posts: 291

Read this: http://sscce.org/

I don't have a week to go through all that code.

You cannot pass a connection. Ever.

Java talks about references to objects, not address of objects which masks what a computer really does. If you have an address/pointer to something within a JVM, there is no way you can pass an address/pointer to that object to another JVM.
Al Johnston
Ranch Hand

Joined: May 02, 2009
Posts: 99

Edward,

I really appreciate your comments. However, I tried to start my example with exactly what I think the problem is in the code. You posted: "Where's the code... let's see it." Then I go and post all the code and you point me to a discussion on best practices in forum posting. Thanks. I did not want to post all that code in the first place.

And, as the subject of my thread suggests, I already know you can't pass a Connection, have no intention of passing a Connection and as far as I can tell I have dereferenced all instances of Connection before any object that uses one is passed to a Client.

I understand how memory works - just a little work with JNI will teach you all you need to know about addresses in memory.

The problem has to be occurring within these data objects because there is no other place in the code that I used a Connection (which is why I did not post all the RMI code in the first post since I presume everyone here already knows what RMI looks like).



All my data objects work similarly. The Connection has been closed and set to null before any caller can ask for any object that takes one of these data objects in the constructor. Yet, somehow I'm holding reference to a Connection and RMI is trying to pass that reference down. I'm trying to figure out how I'm holding reference, not if I should be holding reference to a Connection.

Best,
Al
Manuel Moons
Ranch Hand

Joined: Mar 05, 2002
Posts: 229
If you have references to variables that can/may not be serialized you could use a "transient" variable:

eg.
private transient String password;

Transient variables will lose there value when trying to serialize them.

Hope this helps. I have not read your code, but it might solve your problem!
Al Johnston
Ranch Hand

Joined: May 02, 2009
Posts: 99

Thanks so much Manuel! I have never had reason to use transient variables before. That's a great suggestion. I'm going to modify the code and see if this fixes it.
Al Johnston
Ranch Hand

Joined: May 02, 2009
Posts: 99

That did it! Thanks a ton. This has been days of head aches for me. Lesson learned. Transient keywords are my new best friend.
Manuel Moons
Ranch Hand

Joined: Mar 05, 2002
Posts: 229
Glad to have helped!
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: How to Ensure I'm NOT Passing RMI Objects I don't Mean to
 
Similar Threads
Does this guarantee a unique client?
java.sql.SQLException: Closed Connection
RMI passing objects with ArrayLists of objects as their members.
Nullpointer exception?
HashMap over network via ObjectInputStream does not work properly?