Thinking about using this pattern, it seems that you would only have one RMI server, which is the Factory. Your Factory object would then hand out other remote objects (I am specifically thinking about handing out Data objects or DataAdaptor objects). So the factory object, of which there is only one, looks like this:
and the DataAdaptor object looks like this:
My question is: What does it mean for the server to be actively supporting multiple Remote objects? For example, suppose you have one Factory object, and there are 4 clients, so you have allocated 4 DataAdaptor objects. All together, there are 5 Remote objects. What does this mean in terms of how many socket connections you would be using on the server? Does each Remote object get its own socket, so you will have 5 sockets that the server is using? Or is it only the RMI server which gets its own socket, and all the Remote objects share it?
And then I want to contrast this with a situation where DataAdaptor is your RMI server, and you support 1 DataAdaptor for each client. In that case, the DataAdaptor looks like this:
Trying to be consistent with the example above, you would have 4 RMI servers for your 4 users.
In summary: With the first design, you have 1 RMI server and 4 Remote objects. In the second design, you have 4 RMI servers. And the final question is: from a system resources standpoint, which is better?
Good to see you have not lost interest in the issue and are opening up a new thread on it to get a broader band of discussion. I think the answer is: in both cases the system resources are one and the same (but I will double-check).
If you look at the documentation for the "export method" for unicast remote object, it will tell you that it takes a "remote" object and makes a "unicast remote object a.k.a server out of it".
The other option for making a remote object (really the remote skeleton) available to RMI clients is by "binding" to the registry, which is a relatively light weight task of adding a name-value maping in the RMI registry server's database.
If you want, I can post detailed documentation on the topic as well as the internals of how RMI "servers" actually communicate over TCP. I'm surprised your book doesn't cover this??
Hope this helps. Reza [ June 09, 2005: Message edited by: Reza Rahman ]
Independent Consultant — Author, EJB 3 in Action — Expert Group Member, Java EE 6 and EJB 3.1
Joined: Feb 01, 2005
Another way to get to the bottom of this is to simply try it and use "netstat -a" on a Windows machine and see how many ports RMI has opened (of course this is not the only relevant performance metric...but I think it is the major one...)
Yet another option is to specify the port on the export method and use the same port number more than once. If ports are not sharable, I think you will get a bind exception on the second call.
At any rate, I'll double check and post what I have.
Below is some material to give you a better understand of what the deal is with export/rmiregistry/bind. If you need me to go over some of these in greater detail, let me know (I'll admit I'm a little short on time right now...):
1. This article explores how the internals of RMI itself work: http://www.developer.com/java/other/article.php/10936_3455311_3. This one actually does a very good job, but it is not the one I was originally thiking about. However, I can't seem to find the article now in my mess of magazines...read it carefully, though; can you guess what UnicastRemoteObjects's export method does?
2. Take a look at the Javadoc for UnicastRemoteObject. Notice the parallels between the constructors that are called implicitly by implementors and the export methods? In case you don't take a look at the Java rmi tutorial here: http://java.sun.com/j2se/1.3/docs/guide/rmi/getstart.doc.html. Note the sections on "Define the constructor for the remote object".
However, I came across something very interesting while digging around...RMI actually does support multiple remote objects on the same port (this must be an offshoot of getting rid of explicit skeletons post J2SE 1.3). I verified this by explicitly invoking the constructor with port specification for my UnicastRemoteObjects. Note, however, I'm still not sure if this is default RMI behavior, that is what "anonymous port" really means (I'll test that next as soon as I get home).
Now I'm curious how this is actually accomplished and what the performance impacts are. I bet the answer lies in the TCP packets of the RMI request itself (probably in the form of additional info identifying a unique remote object to invoke). I'll keep you posted if you are interested...as a matter of fact, let me know if you get to it before me...
I'll be busy for the rest of the day, so hopefully you won't need further help or someone else will be willing to help you out...
I verified what the article on RMI internals suggests: the pattern of choosing "anonymous" ports for exporting remote objects (servers) seems to be quite random (I tested on Windows 2000 Server and Red Hat Linux 7). However, there is a high degree of port sharing going on (looks like a about 30-40 remote objects share a port, on average, on my machines).
You could try to specify a single port for all of your remote objects to share, but I have a feeling you have a good chance of running into some kind of performance bottleneck if you do so...
In any case, I'm not sure this is all worth worrying about in the limited scope of this assignment, so ultimately, I would choose what feels right and document it.
Hope this helps. It was a lot of fun playing around with this stuff at any rate...