: stand-alone mode using RMI
Chris Hegarty
Greenhorn
Joined: Sep 04, 2003
Posts: 4
posted
Sep 04, 2003 07:45:00
0
I have a question about how to implement the stand-alone mode. I am using RMI an want to use the same class for both remote and local connections. For remote connections simply do a lookup and for stand-alone create a new object. I have demonstrated a simple example below.
Does this meet the requirements of non-networked mode; no serialization or networking?
public interface Hello extends Remote { String sayHello() throws RemoteException; } public class HelloClient{ static String message = "blank"; static Hello obj = null; public void init() { try { message = obj.sayHello(); } catch (RemoteException e) { System.out.println("HelloClient exception: " + e.getMessage()); e.printStackTrace(); } catch (Exception e) { System.out.println("HelloClient exception: " + e.getMessage()); e.printStackTrace(); } } public static void main(String args[]) { HelloClient hc = new HelloClient(); if (args.length != 0 && args[0].equals("alone")) { System.out.println("alone"); try { obj = new HelloImpl(); //<< LOCAL } catch (RemoteException e) { System.err.println("RemoteException"); } } else { try { obj = (Hello)Naming.lookup("//" + //<< REMOTE "carrots" + "/HelloServer"); } catch (Exception e) { System.err.println("RemoteException"); } } hc.init(); obj=null; System.out.println("message = " + message); } } public class HelloImpl extends UnicastRemoteObject implements Hello { public HelloImpl() throws RemoteException { super(); } public String sayHello() { return "Hello World2!"; } public static void main(String args[]) { try { HelloImpl obj = new HelloImpl(); Naming.rebind("HelloServer", obj); System.out.println("HelloServer bound in registry"); } catch (Exception e) { System.out.println("HelloImpl err: " + e.getMessage()); e.printStackTrace(); } } }
[Andrew: Put code inside [code] blocks so formatting can be preserved.
[ September 05, 2003: Message edited by: Andrew Monkhouse ]
Chris Hegarty
Greenhorn
Joined: Sep 04, 2003
Posts: 4
posted
Sep 04, 2003 09:33:00
0
I can refine this example some what by only extending
RemoteObject
and using java.rmi.server.UnicastRemoteObject.exportObject(<remoteObject>
to export the object if in server mode.
Ken Krebs
Ranch Hand
Joined: Nov 27, 2002
Posts: 451
posted
Sep 04, 2003 12:38:00
0
Chris,
I not sure if this would cause automatic failure, but I wouldn't want to take that chance. Even ignoring that issue, I really don't know why you would want to do it this way.
In my project, I define a Services interface and a ServicesImpl class that does all the heavy lifting, locking/unlocking, accessing the Data class, etc. As far as the gui client code is concerned, all it ever sees is an implementation of Services whether running in standalone or network mode.
When running in standalone mode, my launch code provides the gui with an instance of ServicesImpl but all the gui client knows about it is that it is an implementation of Services.
I also define a RemoteServices interface and a RemoteServicesImpl class extending
UnicastRemoteObject
. RemoteServicesImpl is ultra-simple, it gets an instance of ServicesImpl and delegates all of its work to it.
When running in network mode, my launch code provides the gui with an instance of the generated stub for RemoteServicesImpl but again all the gui client knows about it is that it is an implementation of Services.
NOTE: I use the nice little trick shown in Max's book of defining all methods in my Services interface to throw
IOException
. This allows RemoteServices to simply extend Remote and Services without having to specify anything else at all. This works because
RemoteException
extends
IOException
. The gui has to deal with IOExceptions and any business logic Exceptions that might occur but it doesn't have to supply anything extra for RemoteExceptions.
Hope this helps,
kktec
SCJP1.4 & SCWCD
kktec<br />SCJP, SCWCD, SCJD<br />"What we observe is not nature itself, but nature exposed to our method of questioning." - Werner Heisenberg
Andrew Monkhouse
author and jackaroo
Marshal Commander
Joined: Mar 28, 2003
Posts: 11567
102
I like...
posted
Sep 05, 2003 01:53:00
0
Hi Chris,
Welcome to JavaRanch.
As you may notice, I have put your code inside a [code] block which ensures that indentation is kept. This makes your code more readable, which may help you to get more comments - there are some people who will not read code that is not formatted. If you edit your post above, you should be able to see the start and end code block statements. Also you can look at the
UBB code description
page.
I think
that this does meet the "no networking" requirements.
However I strongly suggest you look at the concept explained by Ken above. I think this is much cleaner, and I have no doubt that this does meet the requirements, so it is a little safer.
Regards, Andrew
The Sun Certified Java Developer Exam with J2SE 5:
paper version from Amazon
,
PDF from Apress
, Online reference:
Books 24x7
Personal blog
Chris Hegarty
Greenhorn
Joined: Sep 04, 2003
Posts: 4
posted
Sep 05, 2003 04:00:00
0
Thanks guys, I think I will go with the suggestion from Ken.
Better safe than sorry!
jhao wang
Greenhorn
Joined: Aug 31, 2003
Posts: 15
posted
Sep 07, 2003 21:08:00
0
Hi,Chris Hegarty, this is my solution:
Code:
----------------------------------------------------------------
public interface Database extends Remote { // business methods such as the findByCriteria() method // all business methods throw RemoteException and any method specific exceptions } public class DatabaseImpl extends UnicastRemoteObject implements Database { // holds a local instance of Data class // converts calls to business methods into the appropriate calls to // the methods of Data class } public class ConnectFactory { // variables, constructors and private methods /** * Returns database interface which contains business methods. * @return database interface which provides business methods * @throws CSRException */ public Database connect() throws CSRException { Database db = null; // standalone mode if(alone) { db = new DatabaseImpl(location); } // network mode else { db = (Database)Naming.lookup("//" + location + "/database"); } return db; } }
You can see that in fact almost all the operation is in Data.class.
When you start the application, the ConnectFactory can return a same database interface to you, yet it was created by defferent ways according to the mode.
I also hope to get suggestions about my code from Andrew Monkhouse and Ken Krebs
Thank you
[Andrew: removed major sections of code]
[ September 08, 2003: Message edited by: Andrew Monkhouse ]
Andrew Monkhouse
author and jackaroo
Marshal Commander
Joined: Mar 28, 2003
Posts: 11567
102
I like...
posted
Sep 08, 2003 02:43:00
0
Hi Jhao,
As you will notice, I have removed some major sections of your code, putting comments in their place to indicate what the classes / interfaces do. While we do allow some small methods to be posted here, I feel that you provided a major part of the solution to the entire server and local / remote mode connectivity issue. I do appreciate that you did try and remove some sections of your code before posting. However I felt that there was too much detail, and lowered the detail level. I believe that we can still answer your request for comments with what I have left. Chris' post, while also containing quite a lot of detail, was not specific to the assignment, so it is more in keeping with our requirements.
Your solution is, in my opinion, identical to Chris'. In both cases you are defining the one interface, with one class that extends that interface, for both local and remote use. Your only real difference is using a connection factory to get your instance of Database, whereas Chris' example used the object directly. I believe that this difference only occured because you were providing your assignment solution - Chris was just providing a proof of concept, so a factory was not required. Given this, the comments that Ken and I provided to Chris also apply to your code.
Regards, Andrew
I agree. Here's the link:
subject: NX: stand-alone mode using RMI
Similar Threads
Applet with RMI ,how to place into Tomcat?
Package usage problem
RMI Example
RMI access denied client/server
exception in client side
All times are in JavaRanch time: GMT-6 in summer, GMT-7 in winter
JForum
|
Paul Wheaton