Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Head First Java RMI Universal Service Browser Question

 
Bob Nedwor
hangman
Ranch Hand
Posts: 215
Eclipse IDE Oracle Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Has anyone seen the "Universal Service Browser" project in K&B's Head First Java book on p.636 (2nd Edition)? I am able to get it to work, but I need to have some classes on both the server machine and the client machine and I don't think this is right. For example, if I don't have the MiniMusicService.class on the server machine, then I can't compile the ServiceServerImpl class without getting: "NoClassDefFoundError: MiniMusicService..."

Futhermore, I need to have it on the client machine, or else when I run the ServiceBrowser and select that service, the app errors out with: "MiniMusicService (no security manager: RMI class loader disabled)"

Thanks for any hints, because the book isn't entirely clear on which classes go on the server and which ones go on the client.
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I haven't seen the project you're asking about, but I can give some pointers about RMI in general...

For example, if I don't have the MiniMusicService.class on the server machine, then I can't compile the ServiceServerImpl class without getting: "NoClassDefFoundError: MiniMusicService..."


You don't need to really think about the "client/server" distinction while compiling... only at runtime. When compiling the implementation class, the interface class has to be present - There's nothing specific to RMI about this, just general Java compilation/classpath stuff.

Futhermore, I need to have it on the client machine, or else when I run the ServiceBrowser and select that service, the app errors out with: "MiniMusicService (no security manager: RMI class loader disabled)"


Here there may be some issues... in old (pre-1.5) days, you could go one of two ways - either package your client with the interface and the stub, or use RMI dynamic classloading (and define a security policy,etc.) to dynamically download classes as they are needed. In 1.5 dynamic RMI stub generation was added - so now I guess you only need to package your interface with your client and the stub gets generated automatically (or you could go the RMI dynamic classloading, security policy, etc. path.)

So, if you're using 1.5, the client needs the client code and the interface. The server needs the server implementations and the interface. If you're using pre-1.5, the client needs the client code, the interface and the stubs. The server needs the server implementations and the interface (and if you are *way* pre-1.5 the server needs the skeleton, too... but that's really ancient...)
 
Bob Nedwor
hangman
Ranch Hand
Posts: 215
Eclipse IDE Oracle Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nate:
Thanks for the explanation. I am using 1.5 on both machines.

I think I need to study the whole RMI concept a little bit better. This is only the 2nd example in the book and there are about six different source files in this example. No skeletons files, but a _stub file is generated, which I know needs to get copied over to the client side.

I just need to get my feet wet in RMI more. It wasn't expected in the SCJP exam, but I am going to need it for SCJD.

Could part of the problem be that when I tried to run it all on the client machine first, just to make sure I had everything working, I ran "rmic" and "rmiregistry," and those are now interfering with what should really be happening on the client side?

--Bob, "the rmi newbie"
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
rmic is the "RMI Compiler" - this is run at compile time, and produces the stub from your RMI interface. You really only need to run this when you compile your code.

rmiregistry is the "RMI Naming Service" - basically, think about this like a hashmap that clients can look in to get a stub to a service. A RMI server uses Naming.rebind() to add itself to the registry with a specific name, and then clients can use Naming.lookup() with the same name and get a stub to that service. You should only have to run rmiregistry on your server machine.

There's an RMI tutorial on JGuru that covers some of this in more detail - go to the section labeled "RMI Architecture" to get a description of the "interface/implementation/stub" stuff, and the section called "Naming Remote Objects" to get some info on how what the RMI registry does.

Have fun!
 
Allion Salvador
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I think that all the examples in the book (the big projects), just show you all the classes with different import statements. I tried it out by putting the whole caboodle into one source code file, with the services classes with default access levels, and I put the client code in a different file. If this helps, send me a message!
:-)
 
Bob Nedwor
hangman
Ranch Hand
Posts: 215
Eclipse IDE Oracle Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Nate and Allion.

That helps a little. I will definitely check out the link to learn more about RMI.

I usually try to follow the format of examples in the book as closely as possible and each time I see an import statement, I assume we are supposed to start an source file. I don't think the intent in this particular exercise was to group things all together. Good Job getting it to work that way, though.
 
Allion Salvador
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
MOOOOOOO

Well, this doesn't do much, does it?!
Don't mention it! I'm only 11 years old!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic