Howdy all, I've got 2 quick questions. 1. I'm using a Factory to obtain either a remote or local instance of a Database Interface for the abstraction of local and remote client interaction. I implement Database using an InvocationHandler and reflection to translate Database calls to local calls or remote calls. Does anyone think that an InvocationHandler is to complex for a Jr. Programmer? Techniclly I'm a Jr. Programmer and I understand them. 2. When I read the instructions to the assignment I got this idea in my head that the server would obtain a location for a db.db file when started up and that the clients would connect to the Server and share the db file the server loaded at startup time. So in other words I thought that if a client wished to open a local file it would specify a filename only and if it wished to connect to a server it would specify an address and port. (no filename) But, reading other comments on this board it looks as though the server is supposed to obtain a filename from the client at connection time and use the client specified .db file. Did I misunderstand the instructions or am I missunderstanding some of the comments on this board? Thanks tons for your help, Mike [ April 17, 2002: Message edited by: Mike Youngstrom ] [ April 17, 2002: Message edited by: Mike Youngstrom ]
2. You are misunderstanding some of the comments. In No case will the client send or tell the server where to find the db.db file. The server tells itself, or the user who starts the server tells it, but never a client. The client, when stating a db.db file means it wants to be in local mode and not even deal with the server.
1. Now that is the key word.
I implement Database using an InvocationHandler and reflection to translate Database calls to local calls or remote calls.
to translate call to local or remote calls. The user should be in one mode only so any calls will be in that mode, there is no translating needed. You Factory is correct in that it returns an instance of either a Local Mode class or a Remote Mode class, so when the client has one of those it never needs to translate, it just calls methods on that instance. Mark
Thanks tons for the comment about #2 It's a huge relief. As far as question #1 let me explain a little more how I'm using InvocationHandler. Client get's an instance of Database using the DBFactory: 1. example remote database
or 2. example local database
Within the factory if the call is example #1 I do
The code for RemoteInvoker may look something like this. (simplified)
Within the factory if the call is example #2 I do something like.
The code for LocalInvoker may look something like this. (simplified)
The InvocationHandlers obviously get more complex once exception handling is put in but I believe because the client runs with the returned Database instance I'm staying true to the requirement of the user staying in one mode or the other. Or am I missing something? All the InvocationHandler does is simplify the creation of Database Implementation classes that might look like this:
Does that make more sence? Thanks again for the comment, Mike [ April 17, 2002: Message edited by: Mike Youngstrom ]
Yes that makes more sense. But it seems a bit overkill. I am unfamiliar with the InvocationHandler, however I know that you don't need this. You want a factory class to return an instance of your data class, or some facsimile of it, like maybe a Facade that contains a implementation of the interface of the Data class. Either way you just create the instance, and return it, no need for the class loader et al. Just out of curiosity, maybe you are trying to dynamically download the stubs? I doubt it, but you can't know that the assessor has a web server to do this, and therefore for this assignment dynamic downloading is not a possibility. OK, back to our regularly scheduled program... If you are looking for the "Connection" object for remote that everyone talks about, you simple extend Remote on the remote class, use rmic to create the stubs for you that you then include with the client. I suggest doing a search on Connection here, and see what yuo get. I hope that helps. And I don't mean to be down on ya for it, but I think it is a little too much for this assignment. Mark
Joined: Apr 17, 2002
O.K. Thanks for the comment, I'll consider removing it since it appears it may be too complex for a Jr. Programmer. I'm a little suprised that the use of InvocationHandlers(Proxy Classes) to implement Facades has not been discussed in this list before. Just for future reference though maybe I'll provide a little more of a description of them for everyone. A Proxy class is a class that dynamiclly creates stub (not RMI related) classes of an array of provided interfaces. It uses an InvocationHandler to process all the method calls of the Proxy class. (When you create a Proxy class you have to provide a ClassLoader I don't know what it's for either it's just in the example in the API docs) Proxy Class API doc The InvocationHandler Interface has a single method in it.
InvocationHandler API doc. The Method passed into invoke() is the method called on the Proxy class. So if needed special handling can be provided for individual methods by checking the method passed into invoke() or the same code can be executed for all the methods invoked. So in the case of facades the majority of methods called on a facade end up being simple pass throughs to the class being facaded. Or they all perform the same type of convertion to call the method on a remote object or something like that. In the case of the Developer Assignment I'm using Sockets instead of RMI so every method called on the facade must be translated and trasmitted to the server in the exact same way. So the facade comes in handy because it makes me only implement the translation and transmission code once for all the methods of my facade interface. Which holds the following advantages. 1. Your translation and communication facade code becomes reusable. If any other interface were needed to be translated and communicated to a server the very same InvocationHandler could be used to do this with Zero new code. 2. Your code becomes more flexible. If a method is added to the facade interface then no new code needs to be implemented in your facade classes. 3. Less bug prone because their is zero code duplication. Anyway, If anyone is interested in seeing how I used the InvocationHandler in my project just ask. Thanks, Mike
Cool, thanks for the information. I also didn't realize that you are using Sockets, which makes my point on using rmic and stubs as your proxy. Now I might rescind my comment of too complex, and maybe it's just to add that reusability aspect to sockets it might be the way to go I'm sorry for making your decision harder again. But I also don't want to lead you down a road that I might not be the best knowledgable about that, since I didn't use Sockets. However, I have used Sockets for a chat program, before, and instead of Proxies, I just passed the serialized Object through the Socket tot he client, which had the class code, to reinstantiate and use. This might also prove why using RMI is easier since all of this is handled for you. and can be good to use in your Pros and Cons protion of the essay exam. Well, I'll shut up now. Mark
Joined: Apr 17, 2002
I was actually thinking it could be fairly useful for RMI as well. In RMI doesn't the client use a Remote Interface to work with the Server where every method must throw RemoteExeptions? So your invocation handler would translate your regular Data Interface method calls into method calls to the Remote Interface which would wrap the RemoteException catching. Anyway, doesn't matter, I think it's about time to let this thread sleep. Mike