Two Laptop Bag*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes RMI Testing 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 » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "RMI Testing" Watch "RMI Testing" New topic
Author

RMI Testing

Mauricio De Maria
Greenhorn

Joined: Apr 02, 2003
Posts: 10
Hi guys, that's my first post on that area. I'm an SCJP with no so much experience in design.
I've just finished reading Max's book (SCJD) and one little thing came to my mind.
Since I don't have easy access to an actual network, is it possible to test an RMI implementation, in only one machine?
In other words, at least to get going before doing the real network test, is it possible to kind off simulate a RMI connection with both server and clients communicating on the same machine? (for debuging purpose)
Has anybody done that?!
Any help would be very much appreciated.
Thanks
S. Ganapathy
Ranch Hand

Joined: Mar 26, 2003
Posts: 194
Run the RMI server in seperate directory, and client in another directory.
frank sun
Ranch Hand

Joined: Apr 11, 2003
Posts: 102
Also, you couldsetup a simulate OS on your current OS platform, there are some tools to implement that.
Frank
Mauricio De Maria
Greenhorn

Joined: Apr 02, 2003
Posts: 10
Is that simple? Ok, I'll try to run them in a different directory then.
Frank do you know a name of any of those simulators?
Thanks guys,
Maur�cio
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11404
    
  81

Hi Mauricio,
There have been several knowledgeable people in this forum that have stated that the examiner will be running the client and server on the one machine.
You do need to have TCP/IP installed and configured on your PC to do this, but most people do have a basic TCP/IP stack installed even if only for connecting to the internet.
One extremely good simulator is VM Ware. It is a commercial product, but they do give you a 30 day free trial. You will need a copy of whatever operating system you want to run in the virtual machine, and you need a reasonably powerful machine to run it. If you do look at it, I suggest you wait until you are close to completing your project, that way you wont have to worry about the license expiring.
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Mauricio De Maria
Greenhorn

Joined: Apr 02, 2003
Posts: 10
Hi Andrew,
First, thank you very much for your comments, they are very much appreciated.
So I guess, for simplicity, I'm gonna try running first on a standalone machine. The simulator doesn't look to me as a very simple task, so maybe I'll try it at the end of the project as you suggested.
I've found a helpful tutorial at http://java.sun.com/j2se/1.4.1/docs/guide/rmi/getstart.doc.html where a simple Helloworld is implemented using the RMI.
In that tutorial, there are two places where an IP address must be provided:
In the server ->
// Bind this object instance to the name "HelloServer"
Naming.rebind("//myhost/HelloServer", obj);
In the client ->
obj = (Hello)Naming.lookup("//" + getCodeBase().getHost() + "/HelloServer");
message = obj.sayHello();

So I guess that by putting my local IP address in the server, in the place of myhost would be alright, correct? (well then I have to start the server and its registry I guess)
After that I think I've got to run the client, from a different DOS console, with different CLASSPATH, so that it would download the remote class and not get it from the variable. Something like that.
I am going the right path?
Any comments are welcome!
Best Regards,
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11404
    
  81

Hi Mauricio,
You might also want to look at the Sun JGuru Fundamentals of RMI short course. This goes into far more depth on what you can do with RMI.
Later, when you have questions, you may also want to look at Sun's RMI and Serialization FAQ

So I guess that by putting my local IP address in the server, in the place of myhost would be alright, correct?

When binding and performing lookups, and you are working on your local machine, you have several options regarding IP addresses and ports.
  • If you are using the standard port, you can leave it all off
  • You can use the server name "localhost"
  • You can use the address 127.0.0.1


  • If you do have a public IP address you can use that as well.
    So the following are all equivelent:

    (well then I have to start the server and its registry I guess)

    You can have the server program start up the registry itself ... it is one extra line in your program, and it makes everything so much easier. Look at the class.
    The alternative is to run a stand alone registry, in which case you need to start it in a seperate window before you start your server.
    If you start the registry in the same directory as your server code, it will look for the stub classes it needs in the directory it starts from, which will make your life a bit easier.
    If you start the registry in a different directory (one with no classes), then it will not know where to get the stub classes from, and it will complain when you try and bind your server. To get around this you will have to specify a codebase to tell the rmiregistry where your stubs are.
    Note to Mark if you are reading this: I know that we dont need to download stubs (and I say the same thing further down) but I cannot seem to do the bind or rebind on an rmiregistry that was started in a different directory unless I specify a codebase. I have seen others say the same thing. If I am missing something, please let me know.
    After that I think I've got to run the client, from a different DOS console, with different CLASSPATH, so that it would download the remote class and not get it from the variable.

    Yes, once the server is up, you run the client.
    Technically you do not download the remote class (unless you have a serializable remote class, which we wont get into yet ). What you download is the stubs that were created when you ran the RMI compiler (rmic).
    But you do not need to download the stubs ... if the stubs are in the client's class path (or jar file) then it will not attempt to download them from the server.
    Most people here recomend providing the stubs in the client jar file, rather than downloading the stubs.
    Regards, Andrew
    Mauricio De Maria
    Greenhorn

    Joined: Apr 02, 2003
    Posts: 10
    Hi Andrew, first of all thanks for your very good explanation on the subject. I would also like to apologize for my delay in answering your message. I was trying to digest the subject... hehehe
    I haven't yet read the article that you've sent me "Sun JGuru Fundamentals of RMI short course", but I'll do it soon. On the other hand I was able to run an example of an RMI connection between a client and a server on a local machine, which encourages me to go on.

    You can have the server program start up the registry itself ... it is one extra line in your program, and it makes everything so much easier. Look at the class.

    That's actually a pretty good idea that I want to implement. I think It would Make my life and the examiner's easier.

    The alternative is to run a stand alone registry, in which case you need to start it in a separate window before you start your server.

    That's actually what I've done. But in the example, It asked me to reset the classpath, so as to have the stubs downloaded by the client. (I think it likes the idea of downloading the stubs)

    If you start the registry in the same directory as your server code, it will look for the stub classes it needs in the directory it starts from, which will make your life a bit easier.
    If you start the registry in a different directory (one with no classes), then it will not know where to get the stub classes from, and it will complain when you try and bind your server. To get around this you will have to specify a codebase to tell the rmiregistry where your stubs are.

    The second option was the one performed in the example. It provided a codebase probably when calling runtime, in a line like:
    java -Djava.rmi.server.codebase=URL

    But you do not need to download the stubs ... if the stubs are in the client's class path (or jar file) then it will not attempt to download them from the server.
    Most people here recommend providing the stubs in the client jar file, rather than downloading the stubs.

    I think now I understand what you mean by that. But is not quite clear in my mind the reason why it would be more suitable to not have it downloaded. Is it because when you download, it is more error prone?!
    Best Regards, and thank you
    Maur�cio De Maria.
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11404
        
      81

    Hi Maur�cio,
    You asked But is not quite clear in my mind the reason why it would be more suitable to not have it downloaded. Is it because when you download, it is more error prone?!
    Downloading stubs is fine and can be desirable (and is esential when downloading a serialized class).
    But think about the command line you have to enter if you want to have downloadable stubs. It will end up with a definition like the one you showed earlier:
    java -Djava.rmi.server.codebase=URL
    Not very user friendly, and just typing that out can be error prone.
    You can set this programatically, which saves the user from trying to type it out, but it means more coding for you, especially trying to code it so that it works no matter where your code is moved to.
    The other aspect is that if you don't need it, then you can save bandwidth by not downloading the stubs, which in turn can mean a faster start up time (although neither issue should concern us with this assignment). I am not sure if worrying about bandwidth savings is even an issue in real life ... if bandwidth was likely to be an issue, I would pull out RMI alltogether and use sockets.
    Some more general comments:
    Since learning to program RMI, I now always start my own RMI Registry from within my program so that I dont have to worry about the codebase.
    For testing the "Unreferenced" code (used for handling client crashes) I programatically change the lease value to around 15 seconds rather than waiting the normal 20 minutes for Java to tell me that my code is unreferenced.
    Regards, Andrew
    Mauricio De Maria
    Greenhorn

    Joined: Apr 02, 2003
    Posts: 10
    Downloading stubs is fine and can be desirable (and is essential when downloading a serialized class).
    But think about the command line you have to enter if you want to have downloadable stubs. It will end up with a definition like the one you showed earlier:
    java -Djava.rmi.server.codebase=URL
    Not very user friendly, and just typing that out can be error prone.
    You can set this programmatically, which saves the user from trying to type it out, but it means more coding for you, especially trying to code it so that it works no matter where your code is moved to.
    The other aspect is that if you don't need it, then you can save bandwidth by not downloading the stubs, which in turn can mean a faster start up time (although neither issue should concern us with this assignment). I am not sure if worrying about bandwidth savings is even an issue in real life ... if bandwidth was likely to be an issue, I would pull out RMI altogether and use sockets.

    Hi Andrew, thanks again for your comments.
    I think now I have a clearer picture on what the possibilities are. Since downloading the stubs is not probably a requirement from the SCJD I think the best thing would be to leave this RMI connection as simple as we can. So, finally I am gonna start the registry from inside the code instead of doing that separately with a codebase provided. There's one last thing I noticed in the code example from Habibi's book: It actually starts the RMI registry from the client. I thought the RMI registry would always be on the server side. Am I missing something?!

    For testing the "Unreferenced" code (used for handling client crashes) I programmatically change the lease value to around 15 seconds rather than waiting the normal 20 minutes for Java to tell me that my code is unreferenced.

    Sorry I didn't understand much about what you just said. What do you mean by "unreferenced code"?
    Best Regards,
    Maur�cio De Maria.
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11404
        
      81

    Hi Maur�cio,
    I noticed in the code example from Habibi's book: It actually starts the RMI registry from the client. I thought the RMI registry would always be on the server side.

    Bad timing - Max is away this week, otherwise I would have liked to hear his comments.
    But personally I cannot see how this would work. You need the RMI Registry running in order for the server to register with it. Starting it from the client makes no sense to me.
    What do you mean by "unreferenced code"?

    Ooops - jumped ahead of myself. java.rmi.server.Unreferenced is part of one solution to the following problem:
    What happens if your client locks a record, then crashes sometiime before unlocking the record? If only the client that locked the record can unlock it then you are in trouble - no one else can unlock it.
    I shouldnt have raised this issue before you started thinking about it, because now I have indicated my solution before you started thinking about it yourself. Sorry about that.
    Regards, Andrew
    Mauricio De Maria
    Greenhorn

    Joined: Apr 02, 2003
    Posts: 10
    Bad timing - Max is away this week, otherwise I would have liked to hear his comments.
    But personally I cannot see how this would work. You need the RMI Registry running in order for the server to register with it. Starting it from the client makes no sense to me.

    Recently I ran Max's DVD example and it actually starts the RMI Registry from the server side. The only thing weird that I found was the code below:

    He actually does have a register() method call on the server side too (uncommented).. What I didn't understand is why it has it commented on the first piece of code above. In other words, to start his RMI registry he does it on the server side, but the question is: Why does he have the commented line on the client side? I don't get it.

    Ooops - jumped ahead of myself. java.rmi.server.Unreferenced is part of one solution to the following problem:
    What happens if your client locks a record, then crashes sometiime before unlocking the record? If only the client that locked the record can unlock it then you are in trouble - no one else can unlock it.

    Well I think I've read something about that somewhere in this forum. I would probably try something like a locking timeout. But hey, to be honest, if this is not a exam requirement I won't bother. I'm a inexperienced programmer already having some trouble to understand all of that. Thus I'll try to keep it as simple as possible, preferably covering all the requirements and that's it.

    I shouldnt have raised this issue before you started thinking about it, because now I have indicated my solution before you started thinking about it yourself. Sorry about that.

    Man in truth I'm very grateful for all the issues we have been raising here so far. Once again I'd like to thank you! You've been very helpful!
    Best Regards,
    Mauricio De Maria
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11404
        
      81

    Hi Maur�cio,
    Ok, I understand what Max is doing in this code.
    The normal situation is that you have to start the server in one JVM and the client in another.
    What the commented out code allows for is that the client itself can call the code in the server application which starts up the RMI Registry and registers the the server functionality with the RMI Registry.
    So if you uncommented that line in the client code you could start both the server and the client from the one application.
    I cant think of a valid reason for doing this in Java in a real life situation, but for testing it could make life a little easier since you dont have to manually start the server in a seperate JVM.
    I would probably try something like a locking timeout.

    If your instructions can allow for this, then that may be a good solution.
    I did the Fly By Night assignment, and I couldnt see any way of having timeouts with the code and instructions supplied, so I used unreferenced instead.
    I didnt have anything in my instructions that explicitly required orphaned locks to be unlocked, but I consider it to be required for a decent server solution. I could probably also have left it out and just made a comment in my documentation that I had considered it and decided not to add things not in the documentation.
    I'm a inexperienced programmer already having some trouble to understand all of that. Thus I'll try to keep it as simple as possible

    This may be my biggest failing I have been developing back end solutions (particularly for the airline industry) for a large number of years, and I kept wanting to add hooks and/or code that was way outside of the requirements, because "a real airline would need this" .... I kept having to pull myself back and stick to the spec
    Regards, Andrew
     
    It is sorta covered in the JavaRanch Style Guide.
     
    subject: RMI Testing
     
    Similar Threads
    RMI Advantages / Disadvantages
    RMI
    rmi/iiop problems on xp & websphere
    Find a Folder in Remote Machine
    How to find a machine which is nearest in location?