(1) Define a remote service interface with a creation method createProxy()
(2) Adapt the code connecting the base and the meta-level by defining a wrapper class around ProxyFactory. This wrapper is a remote object that implements the remote interface of step 1 and delegates the binding of base objects to its aggregate, the ProxyFactory.
(3) Make base objects used as parameters or as return values of a remote method call serializable.
(4) Define an HTTP service class to allow dynamic class loading using RMIClassLoader.
For the first step, defining a remote service interface is part of any PMI implementation in order that the client can communication its queries to the server through the layers of the RMI system architecture. In our case, the remote interface offers a method that allows client objects at the base level to bind themselves to meta-objects on the server side. Figure 9 shows a pseudo IProxyFactory, where the first Object parameter refers to the bound to a proxy and consecutive dots mean possible extensions, depending on the application. Remote service interface such as IProxyFactory must be visible to both client and server at compile time.
For the second step, Figure 10 depicts a pseudo implementation of ProxyFactoryWrapper. It implements the remote interface IProxyFactory and thus defines a remote object. It also extends UnicastRemote Object allowing the creation of a simple remote object that supports unicast (point-to-point) remote communication and uses RMI’s default sockets-based transport for communication [18]. Although this is not the only way for clients to connect to a remote serverice implementation, it is compatible with clients’JVMs that run on JDK 1.1.x .
Notice that ProxyFactoryWrapper uses ProxyFactory to create the proxy and attaches an application object to it. This is part of adapting the code of the single-application architecture of Figure 4 to the distributed architecture of Figure 8.
For the third step, client object to be attached to meta-objects on the server side are passed as parameters through ProxyFactoryWrapper methods. These and all other objects that need to be exchanged between client and server as parameters or as return types must be serialized, i.e. implement java.io.serializable interface.Serialization is necessary to conform to the RMI mechanism of sending object data over the network wire. The objects are then de-serialized in the remote JVM and made ready for use by the application that needs them.
For the fourth and final step, RMI supports remote dynamic class loading through the RMIClassLoader. The property-Djava.rmi.server.condebase=<URL> must be specified to allow the RMI system to identify the resources on the network and dynamically load the required classes. We may specify the path by setting-Djava.rmi.server.codedbase=file://<class path> or an HTTP(or FTP) servers by setting –Djava.rmi.server.codebase=http://<resource name>. In the latter case,active servers on the client as well as on the server side are necessary to aid the delivery of class files between JVMs on both sides. If a serialized object is passed from one JVM to another, the receiving machine needs to load the class file of that object. In passing the object, the RMI system embeds a URL specifying where on the network this class file can be found and asks the HTTP server to deliver the file on request.
Figure 10.Remote ProxyFactoryWrapper delegates bingding of a base object to ProxyFacory.
Figure 11.Class diagram in the distributed RMI environment.
The class diagram of Figure 11 shows the main classes needed to implement the distributed system, according to the transformation algorithm described previously. Notice the remote layer consisting of ProxyFactoryWrapper, IProxyFactory, java.rmi.server.UnicastRemoteObject and rmi.java.Remote are inserted between the meta-level and the base-level classes of Figure 3.
To explain how to implement the algorithm described by steps 1-4, we consider the single application system example discussed in the previous section. We consider the single application system example discussed in the previous section. We concentrate on the features related to transforming this application into a distributed RMI-based system. In the distributed system, the reusable code becomes part of the server implementation and consists of three units. The first is the interface IPropertyChangeSupport, to allow the registering and removing of listener objects ass well as firing a PropertyChangeEvent to notify the listeners once the object’s state is modified. The second is BeanProxy, to provide the reusable code by implementing the interfaces InvocationHandler and IpropertyChangeSupport. The third is the BeanProxyFactory, to deliver a reference to a proxy object.
Distributing the system requires a server process on the server side. Figure 12 shows the class BeanProxyServiceRegistration with the main method to start the server. A security manager to control access to the resources from downloaded code to run within the server virtual machine is installed (line 6). The security policy can be set using the –Djava.security.policy property.Next,BeanProxyWrapper(see Figure 4) is instantiated and bound to an arbitrary name (lines 9and 10). The client process looks up the remote object by using this name. By registering the service, the server process is completed and waits for client requests running on different JVMs on the network.
Figure12~13~14
We now turn to the communication interface and define, as required in the first step, the remote interface as in Figure 13. This interface must be known to both the client and server.
As required in the second step of the transformation algorithm, we employ the adapter pattern of Gamma et al. [5] and wrap the BeanProxyFactory in a remote object BeanProxyFactoryWrapper as in Figure 14.
Figure 15
Having established the generic service on the server side and a generic communication interface, all of which reside in the meta-level, we now turn to the client side and consider a simple application at the base level involving a Point object and a client object as listener. The attributes of the Point object are supposed to be customized to become active JavaBeans properties. The point class implements a serializable interface IPoint, which defines get and set methods for the attributes. Figure 15 shows an example of a client listener class(implements PropertyChangeListener,lines 8-11). The client request begins by installing a security manager (line 14). The security manager is necessary, because, as with the server, the RMI system could be downloading code to the client. In this example, the BeanProxyFactoryWrapper’s stub is downloaded. After installing a security manager, the base object is created (line 15) and the client constructs a name used to look up an IBeanProxyFactory remote object (line 17 and 18). The value of the first command line argument, args[0], is the name of the remote host on which the IBeanProxyFactory object runs.args[1] specifies the port that the remote object uses to accept requests. The client uses the Naming. lookup < ) method to look up the remote object by name in the remote host's registry (line 19). With the help of the remote object, the proxy object is created (line 21). In creating the proxy, the base object is attached by passing it as parameter, together with a listener object Invoking a set method on the proxy causes the corresponding object attribute to acquire a new value and an event (PropertyChangeEvent) to be fired informing the listener of the state change. In this way, the attributes of the base object behave as active propertiesof JavaBeans.
As in the server case, the client defines a security policy and may use a Web server to download the classes needed by the RMI system on its side dynamically. The client may, however, provide a URL path expression to indicate where the classes will be made available. In our example, these classes are Point, IPoint and BeanProxyClient.
CORBA implementation
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] 下一页
分布式环境中动态代理的应用外文翻译 第3页下载如图片无法显示或论文不完整,请联系qq752018766