• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

RMI Advantages / Disadvantages

 
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone,
I'm just starting my assignemnt and I've noticed from most of the postings that everyone seems to have used RMI to implement the networking part of the assignment.
Can someone tell me what advantages and disadvantages there are of using RMI over TCP/IP socket connections?
 
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OOOO, let me answer this one, since I didn't have any real disadvantages on my essay Exam, which I wrote. So it gives me a chance to try again.
Advantages:
1. Handles threads for you
2. Handles Sockets for you
3. Nice GC of lost clients. ie Unreferenced
4. Marshalls objects for you
5. Dynamic loading of classes are available.
6. Can also make changes on the server end, that might not mean you need to change anything on the client side
Disadvantages
1. Strictly Java. Cannot use with other code outside Java
2. Cannot guarantee that a client will always use the same thread in consecutive calls. Meaning you need to write a mechanism for identifying the client yourself
3. I think it is more Hackable, security needs to be monitored more closely.
See I always get stuck with the disadvatages. I can come up with 2 good ones, and falter on a third.
But hope that helps, in my brevity.
Mark
 
Jason Moors
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot, looks like I'd better do some reading on the subject.
One last question, you didn't mention performance, all the additional GC, Marshalling of objects etc, must come with some performance overhead?? Can RMI handle a large number of clients??
Thanks again
Jason.
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah yes, that was one of the other disadvantages I have seen. See now I will always have three good disadvantages rather than my usual 2.
Yes I believe there is a speed loss in RMI vs Object Serialization, as I had read, but it didn't bother me none
Mark
 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Based on your suggestion, Can I get the following result?
Advantages of RMI:
1. Handles threads for you
Serialized Objects needs to handle threads by developer?
2. Handles Sockets for you
Serialized Objects needs to handle Sockets by developer?
3. Nice GC of lost clients. ie Unreferenced.
Serialized Objects needs to handle GC by developer?
4. Marshalls objects for you
Serialized Objects needs to handle Marshalls by developer?

5. Dynamic loading of classes are available.
Serialized Objects needs to handle loading by developer?
6. Can also make changes on the server end, that might not mean you need to change anything on the client side.
Serialized Objects needs to change the client if
the server make changes?
Disadvantages of RMI
1. Strictly Java. Cannot use with other code outside Java.
Serialized Objects can be used with other code outside Java?
2. Cannot guarantee that a client will always use the same thread in consecutive calls. Meaning you need to write a mechanism for identifying the client yourself
Serialized Objects Can guarantee that a client will always use the same thread in consecutive calls?
Am I right?
thanks.1. Handles threads for you2. Handles Sockets for you3. Nice GC of lost clients. ie Unreferenced.4. Marshalls objects for you5. Dynamic loading of classes are available.6. Can also make changes on the server end, that might not mean you need to change anything on the client side.
 
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm using sockets for the SCJD beta. I think RMI makes the source code messy and complicates testing. For a simple project, I don't think I gain any benefits from using RMI...
 
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tybon,


I think RMI makes the source code messy and complicates testing.


Really? Having done socket programming in C on Berkley Unix, I would say that was messy. For RMI, apart from registering your remote objects on the server and locating them from the client, it's just like working with any other object, which to me seems a whole lot cleaner than sending and decoding proprietary messages over sockets. To extend a sockets solution you have to extend the protocol. To extend an RMI solution, you extend or add new classes, just like in a non-distributed application.
Just my two cents,
Michael Morris
 
Tybon Wu
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Michael. I agree that I will choose RMI over sockets in a "real world" project any day. Programming sockets becomes more tedious than RMI as the project size grows. But for SCJD, I can whip up the networking code using sockets much quicker than using RMI. No need to worry about implementing remote interfaces, catching remote exceptions, generating crap load of stubs and skeletons, and the whole issue of registering and locating remote objects. That's too much overhead and too many design decisions just for sending a bloody character! However, for people who are not familiar with RMI, SCJD is a good opportunity to use it.
 
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
About the RMI disadvantages:
Just wanted to comment that both serialized objects and RMI are completely Java-specific and cannot inherently interact with anything non-java. For that, you'd need to do something WebServices oriented. Also, using sockets, you could guarantee that each request from a given client use handled in the same Thread, but you would have to write that code yourself, and it would not be pretty.
In terms of marshalling objects, I don't see that much difference since you can so easily call writeObject() with a Query object and the whole object graph will go over the wire. With RMI, you get easily exposed methods that become your API, whereas with sockets you have to create your own. If you choose to do silly things like send the method name and then each parameter or send some request code int, RMI is much cleaner, but it you have a nice use of the Command pattern, serializing that over the wire can work pretty well. Serialized command objects would work well for something like Prevayler
Also for this project, it's so simple that 5 and 6 don't seem to apply that strongly. I can imagine cases where you'd need to update the client's jar file or not after changing the server side of either transport mechanism.
For RMI advantages, I would add HTTP tunnelling, which is provided by Sun (although I don't know how transparently, but in any case you would have to write a ton of code to tunnel your socket stuff)
In terms of performance, I've always heard that RMI will be slower due to overhead, but it's all tradeoffs. You could optimize either approach to send as little data over the wire, but now you're back in procedural land trading maintainability/clarity for performance.
One RMI disadvantage I would list is it's dependence on an additional compilation tool (rmic). I've always been wary and shied away from such things as they complicate development and have always seemed like cop-out hacks to me. I much prefer things that can run javac-only bytecode.
I might also say something about RMI having extra complexity. I have been working in an Extreme Programming environment recently, and we really try to trim the code to doing just what's necessary, so if you've just got one server object, just connect to it directly. Running a registry and looking things up in it is bloat.
Now that I've added my two cents, let me say that I went with RMI because it required fewer lines of code, seemed more common, and my study book recommended RMI unless you had extended experience with server sockets.
 
Pete Lyons
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Prevayler (there was a type-o in my previous post)
 
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi
How easy it is to extend an RMI application to RMI-IIOP for communication with non Java code.
Is RMI extensible?. Can an application written using RMI could be easily migrated to RMI-IIOP
thanks
Chandru
 
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ultimately I think there is one "killer argument" in favour of RMI.
The requirements state that you must have a client-side object implementing the Data API. Obviously, you will have a Data-like object on the server no matter what implementation you choose. This means that your multi-threaded remote communication protocol ultimately needs to be exposed using Java method call semantics.
Well, there is a multi-threaded remote communication technology that was specifically created to expose remote Java objects using normal Java method call semantics. It's called RMI. If you see a problem that looks like a nail, and you have a tool that looks like a hammer, use the tool. Don't ignore the hammer and go into the smithy to create your own tool.
Ok. That's polemic and oversimplified; but if you use Sockets, that's also the argument you will have to defend yourself against in the design documentation
I do not think RMI is any more hackable than Sockets. To the list of advantages I would add that it naturally uses method call semantics and is therefore a great fit with the Data-like object requirement.
Not all the listed Socket advantages can convince me: "No need to worry about implementing remote interfaces" -- you'll have to implement the Data interface regardless. No difference really. "Catching remote exceptions" -- well, with Sockets you'll have to catch an even wider range of exceptions instead: all of IOException (of which RemoteException is merely a subclass). So arguably Sockets are even worse. "Generating crap load of stubs and skeletons" -- all of four, or two if you use 1.2 compatible RMI. And, given that method-call semantics are required, with Sockets you effectively end up writing some yourself; I'd rather generate them! "And the whole issue of registering and locating remote objects" -- Granted. It gives a useful degree of extra flexibility but that is admittedly not being used in the FBN project.
- Peter
[ February 10, 2003: Message edited by: Peter den Haan ]
 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm in the process of making this decision (again) myself. I may be over-analyzing the problem, but there is one sticky point with RMI that hasn't been mentioned. The requirements state that one must have a client-side object that implement ALL public Data API. This includes the lock/unlock API.
I'm planning to add an additional remote method for booking a flight that will lock/unlock in its server-side implementation to avoid lock/unlock over the network, but the API for lock/unlock over the network will still exist per the requirements.
Now there's no requirement that states that the server must be smart enough to clean up after a client that terminates while a lock is held, but in reality this would be a wise practice if one publishes an API for lock/unlock over the network. This feature would be much easier to implement in a socket-based implementation as the server receives immediate notification when a client disconnects. I believe it's possible to receive this kind of notification with RMI through an obscure timeout setting, but I don't think any immediate notification is provided.
I'm still likely to use RMI for my project, but in the real world when clients can tie up resources over the network and servers need to know when clients die RMI doesn't seem to be the best choice.
- John
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

servers need to know when clients die RMI doesn't seem to be the best choice.


Unreferenced interface.
Mark
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Immordino:
[...] there is one sticky point with RMI that hasn't been mentioned. The requirements state that one must have a client-side object that implement ALL public Data API. This includes the lock/unlock API.

And you can have an RMI-callable server-side API the stub for which is this client-side object. Including lock and unlock, without modification

I'm planning to add an additional remote method for booking a flight that will lock/unlock in its server-side implementation to avoid lock/unlock over the network

Think. Long. Hard. Thoroughly. Maybe read my response in this thread. See the error of your ways and repent

This [cleanup] feature would be much easier to implement in a socket-based implementation as the server receives immediate notification when a client disconnects.

But do you? When a client disconnects normally, perhaps; but a client would've called close() under those circumstances anyway. In fact, unless you use TCP/IP keepalive you will get no notification whatsoever of network problems severing the connection between client and server. The range of fault conditions that can be dealt with more easily using Sockets is fairly narrow, I think.
My RMI-based cleanup code (using Unreferenced, as indicated by Mark) counted three lines, including the method header and closing brace but not including comments; shall we take bets on how socket-based cleanup with similar functionality pans out?
- Peter
[ February 10, 2003: Message edited by: Peter den Haan ]
 
John Immordino
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mark Spritzler:

Unreferenced interface.
Mark


Unreferenced == Unrealistic
Unreferenced is only useful if each client is given a separate server reference (sometimes good, but not always) and only provides immediate notification if the client terminates normally or drops the reference gracefully.
If the client crashes or otherwise terminates abnormally, the server isn't notified until after the lease expires (that obscure timeout to which I referred previously, "java.rmi.dgc.leaseValue", which defaults to 10 minutes). If you adjust the lease value to be too low, your references may go stale between calls during normal operation. Waiting around 10 minutes after a client dies to clean up after it isn't reasonable, either, especially if that client attempts to log back in and grab the same resource(s).
Some folks work around this by sending client heartbeats, which is fine for a small number of clients, but can cause network storms when that number grows.
RMI has its uses, but sometimes you need to know about some of those gory details that it hides from you.
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Immordino:
[...] If you adjust the lease value to be too low, your references may go stale between calls during normal operation. Waiting around 10 minutes after a client dies to clean up after it isn't reasonable, either, especially if that client attempts to log back in and grab the same resource(s).
Some folks work around this by sending client heartbeats, which is fine for a small number of clients

Really? At first sight that seems plain silly. What are RMI leases, if not a sophisticated type of heartbeat implementation? What does a heartbeat do that a lease doesn't?

but can cause network storms when that number grows.

If you want guaranteed notification within a given time, there is no way around this -- no matter what protocol you choose or what layer you implement this in: application (heartbeat), RPC layer (RMI lease) or network protocol (keepalive); you will have a network overhead that increases with the number of users connected at any given time.
- Peter
 
John Immordino
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let's address these issues 1 at a time:

Originally posted by Peter den Haan:
Think. Long. Hard. Thoroughly. Maybe read my response in this thread. See the error of your ways and repent
[ February 10, 2003: Message edited by: Peter den Haan ][/QB]


I agree that an important part of the exercise is to think through these issues, but I don't agree that Sun is intentionally nudging me toward a bad design. You make valid point about separation of database and business logic, certainly one worth considering. If, however, if have to choose between a design that will create less problems for end-users (less network traffic) and other developers (less chance of a deadlock when someone changes the client to send requests in a background thread, etc.) in the long-run and a design that is purer from an OO point-of-view, OO loses every time. The point should be that I make that decision consciously with a command of the issues and can defend my decision in my documentation.

Originally posted by Peter den Haan:
In fact, unless you use TCP/IP keepalive you will get no notification whatsoever of network problems severing the connection between client and server.
[ February 10, 2003: Message edited by: Peter den Haan ][/QB]


In a typical JDK1.3 thread-per-client implementation your server hangs a read on a client socket and responds to the client requests it reads. If the client terminates abnormally the server immediately receives an IOException as a result of that read call. Likewise, in a more scalable, non-blocking NIO-based JDK1.4 implementation you select() on a set of SocketChannels and again you receive an IOException if a SocketChannel closes during the select call. This isn't notification, but an efficient server will not spend much time between reads or selects on a given client socket, so it will know if a client terminates in short order.

Originally posted by Peter den Haan:
My RMI-based cleanup code (using Unreferenced, as indicated by Mark) counted three lines, including the method header and closing brace but not including comments; shall we take bets on how socket-based cleanup with similar functionality pans out?
[ February 10, 2003: Message edited by: Peter den Haan ][/QB]


It would be foolish to compare lines of code in an RMI vs. socket-based implementation. That's not the point. The point is that your 3 clean lines of code won't be called for at least 10 minutes if your client crashes. If you can live with this, I can too.
Now on to your next post:

Originally posted by Peter den Haan:
Really? At first sight that seems plain silly. What are RMI leases, if not a sophisticated type of heartbeat implementation? What does a heartbeat do that a lease doesn't?
[ February 10, 2003: Message edited by: Peter den Haan ][/QB]


A lease is passive, a heartbeat is active. A lease may expire if your client terminates or it may expire if your client doesn't call the server for a while. A heartbeat ALWAYS means the client is alive, whether it's sending other messages to the server or not. This is the key difference - references never go stale in a heartbeat situation. The price you pay on the client side is usually an additional thread that does nothing but sleep and send heartbeats. The gain is that the server knows when a client terminates abnormally in a shorter period of time because the heartbeat period is much shorter than a lease period.

Originally posted by Peter den Haan:
If you want guaranteed notification within a given time, there is no way around this -- no matter what protocol you choose or what layer you implement this in: application (heartbeat), RPC layer (RMI lease) or network protocol (keepalive);
[ February 10, 2003: Message edited by: Peter den Haan ][/QB]


See my point on reading and selection on sockets above.

Originally posted by Peter den Haan:
you will have a network overhead that increases with the number of users connected at any given time.
[ February 10, 2003: Message edited by: Peter den Haan ][/QB]


Of course your network traffic increases as clients increase. My point was in the context of a heartbeat implementation - you can have GUI-based clients whose requests are infrequent and still have a single server that can handle a lot of clients. When you add the constant overhead of heartbeat messages from each client your server sees a lot more traffic than just the infrequent client requests. I should have said that for a given number of clients, a server is much more loaded in a heartbeat implementation than in a lease implementation.
After all that, I still plan to use RMI - it's appropriate for this project. I'm just trying to point out that this is not always the case. If Sun disagrees, why did they invest so much time creating NIO to "enable scalable servers"?
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Immordino:
[...] I don't agree that Sun is intentionally nudging me toward a bad design.

Ok. You walk up to the guys from Oracle, IBM (DB2), Microsoft (SQL Server), Sybase, etc, and tell them that they've been suckered into building their businesses on an inherently bad design. I'll watch
In fact, if the Oracle guy is one from the old school he may grimace and silently agree with you. You know, Oracle have tried for a while to persuade everyone to integrate middle-tier logic on their database server, to the extent of hosting a complete application server in there. People didn't bite. You know why? Because it didn't work.
Database servers have a legitimate reason for existence as separate entities.
Sun is nudging you towards a traditional client/server design. It has its faults, but it's not nearly as bad as you make it out to be. In fact, don't they mention as much somewhere in the instructions?

If the client terminates abnormally the server immediately receives an IOException as a result of that read call.

I didn't dispute that -- but how does it respond to a network outage? It won't. That's where TCP keepalive kicks in.

It would be foolish to compare lines of code in an RMI vs. socket-based implementation. That's not the point. The point is that your 3 clean lines of code won't be called for at least 10 minutes if your client crashes. If you can live with this, I can too.

Let's not get hung up about the 10 minutes; changing that is just a system property away. You can easily crank this down to the 10-30 second mark, depending on the number of clients and the type of connectivity we're talking about, and that is quite acceptable in my book.
But that's not the point either. The point is that the instructions tell you to choose simplicity over performance. Now, does "performance" just mean speed?

A lease is passive, a heartbeat is active. A lease may expire if your client terminates or it may expire if your client doesn't call the server for a while. A heartbeat ALWAYS means the client is alive, whether it's sending other messages to the server or not.

Sorry, I may be a bit thick tonight but I fail to see the your point. Whether the client sends a packet to the server every 10 seconds to renew its lease, or whether it sends a packet to the server every 10 seconds as a heartbeat, the difference is merely semantical. In either case, you can conclude after 20 seconds of silence that the client is probably dead.
Except that you get the lease functionality for free, including a nice notification mechanism after those 20 seconds.

[...] I should have said that for a given number of clients, a server is much more loaded in a heartbeat implementation than in a lease implementation.

I don't see why that would be (OK, so you don't get lease renewals when there's nothing to lease, but in the FBN application every client always has a lease anyway).

After all that, I still plan to use RMI - it's appropriate for this project. I'm just trying to point out that this is not always the case. If Sun disagrees, why did they invest so much time creating NIO to "enable scalable servers"?

NIO is not at all a replacement for RMI; it's a replacement for java.io.* and java.net.*. NIO is more scalable because, among other things, it doesn't force you to waste a precious thread on every connection you are servicing.
In fact, it is eminently possible to write an RMI implementation using NIO which would be much more scalable than the current one. Obviously, the RMI layer will like any abstraction layer always introduce a performance penalty, but I'm not convinced that its scalability is inherently so much worse than sockets for the type of application we're talking about here.
- Peter
 
That feels good. Thanks. Here's a tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic