5

If i want to enable 'two way' communication in my RMI Application (That is, allow the server to invoke methods on the client, as well as the client to invoke methods on the server), is the simplest way to make the client into a Remote class as well?

Also if i intend to pass instances of my client to server as a method parameter, am i correct in thinking that there is no need to add the 'client class' to the rmiregistry?

And one final question, do all of my classes still need to be compiled in the same place? I.E can i compile server and client on two entirely independent machines and expect them to communicate properly?

* EDIT **

One more question, my question makes reference to my client interface (IClient): it has an arraylist (so i have ArrayList<IClient>) to store new instances of the client so the server can keep track of registered clients. When i attempt to compile the server on a different machine, it complains that it cant find IClient - obviously, as IClient is on the client machine. How do i get around this?

richzilla
  • 40,440
  • 14
  • 56
  • 86

3 Answers3

3

You're right in all your assumptions.

You don't have to add your remotely callable client classes to the rmi registry but you still have to export them.

The only caveat with the compilation is that they have to be done with the same version of java with the same compiler settings (at least those affecting RMI stub generation).

DwB
  • 37,124
  • 11
  • 56
  • 82
biziclop
  • 48,926
  • 12
  • 77
  • 104
  • you shouldn't be using rmi stubs, they have been unnecessary for years. and, for the most part, jdk 5 and 6 will communicate just fine over RMI (there were some issues in one of the released versions of jdk 6, but they were fixed). – jtahlborn Jan 26 '11 at 21:44
  • @jtahlborn Thanks for the correction, the last time I used RMI was indeed under 1.4, but the point is just to compile them in a similar manner. – biziclop Jan 26 '11 at 21:51
3

If you have any requirements that the client or server will be behind a firewall in the future deployments, stay away from RMI. You are asking for trouble. Especially if you want the server to call the client.

Here are two alternative solutions that worked well for us:

  • have the client call the server with the server blocking the call until data is available for the client. This uses up a thread per client (if you don't use NIO), but is easy to implement. Return null once in a while to prevent a long running call from the client to be closed by the firewall (depending on the firewall config, of course)

  • if you want nice java interfaces to play with, consider Hessian which is very light-weight, runs on top of HTTP and does not bother with an RMI registry or similar stuff

  • if you intend to open up the server side to other clients, Hessian is still a good choice, but if scaling out is a concern, look into a RESTful architectur style.

Jochen Bedersdorfer
  • 4,093
  • 24
  • 26
0

Re your final question, the remote interface classes and all classes they depend on and so on recursively until closure must be present on both hosts.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • so the `IClient` interface has to be available to the server at compile time? i thought the point of rmi was that i could load classes dynamically that it had never seen before (or have i misunderstood somewhere)? – richzilla Jan 27 '11 at 00:55
  • At compile time and at run time. The point of RMI *codebase feature* is that the classes that *implement* interfaces or abstract classes in the remote interface can be loaded dynamically. However the remote interface itself and everything it depends on is static in this sense. – user207421 Jan 29 '11 at 01:08