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 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.
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.
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.