![]() |
|||
![]() ![]() |
![]() |
![]()
|
![]() |
Multitier ArchitecturesIn Chapter 8, we discussed different approaches to software partitioning. The next example uses the Remote Method Invocation (RMI) of Java 1.1. Remote Method Invocation and JDBCRemote method invocation is now part of Java Development Kit 1.1. As we saw in the chapter discussing three-tiered approaches, RMI allows Java objects to be distributed and shared accross computers and networks. This example uses RMI between the client and the middleware, and JDBC between the middleware and the database server. RMI combined with JDBC for database access is a simple, but efficient, enabler for software partitioning. Indeed, as in this example, the client performs presentation (GUI) tasks only, the middleware stores the applications logic, and the database provides a persistent and coherent storage for the data. This example deals with cars. In this example, all the cars are built in hypothetical car factories, and there is one factory for each different car brand. Clients are allowed to invoke various methods on the cars and factories, although these objects are not local client objects to them. They are remote objects. This means that all methods called on these objects are executed where these objects reside that is, on the RMI server. If parameters must be passed to such methods, they are serialized by RMI and passed to the server object that will deserialize them. The example has these classes:
The client only has access to the Car and CarFactory interfaces. All methods invoked on these objects are actually implemented within the RMI server, which, in turn, performs the calls to the database through JDBC. Figure 10-20 illustrates the whole architecture for this example.
Instead of providing object persistency at the Car level, a simpler option was choosen: the CarFactory level provides persistent storage. Practically, this means information about the car factories is saved in a database table and loaded by the CarFactoryImpl constructor. The database immediately reflects all updates of the car factories. Another option is to save the different instances of CarFactory in their finalize() method whenever the RMI server program terminates. Database Side The data structure is quite simple. Here is the SQL to create the table used for this example. The primary key is composed of two fields: serialno and brand. CREATE TABLE cars (serialno INT NULL, brand VARCHAR(12) NULL, model VARCHAR(12) NULL, color VARCHAR(12) NULL, price INT NULL, owner VARCHAR(12) NULL) GO INSERT INTO cars VALUES (1000000, 'Volkswagen', 'Golf GL', 'black', NULL, '') GO The following SQL statement queries the content of the table after a few executions of the RMI client and RMI server: 1> SELECT * FROM cars 2> ORDER BY brand, serialno 3> GO serialno brand model color price owner ----------- ------------ ------------ ------------ ----------- ------------ 1000001 Audi A6 black NULL 1000002 Audi A8 yellow NULL 1000003 Audi A6 black NULL 1000004 Audi A8 yellow NULL 1000005 Audi A6 black NULL 1000006 Audi A8 yellow NULL 1000007 Audi A6 black NULL 1000008 Audi A8 yellow NULL 1000001 BMW 528i fjordgrau NULL 1000002 BMW 750Li articsilber NULL 1000003 BMW 528i fjordgrau NULL 1000004 BMW 750Li articsilber NULL 1000005 BMW 528i fjordgrau NULL 1000006 BMW 750Li articsilber NULL 1000007 BMW 528i fjordgrau NULL 1000008 BMW 750Li articsilber NULL 1000000 Volkswagen Golf GL black NULL 1000001 Volkswagen Golf CL darkred NULL 1000002 Volkswagen Golf CL darkred NULL 1000003 Volkswagen Golf CL darkred NULL 1000004 Volkswagen Golf CL darkred NULL (21 rows affected) RMI Server Side A script file starts the server and an RMI service called the RMI registry. As soon as it launches, the CarSupplierServer object recreates car factories and cars from the data in the database. CarFactory objects are thus created and bound to a name. Client lookups use this name to obtain references to these remote objects. Here is the output of the CarSupplierServer when launched on Unix (Windows users: the RMI registry command must be executed in a separate DOS shell). csh: start starting registy [1] 7852 starting CarSupplierServer press CTRL-C to interrupt server type: java CarSales to start client Creating Car Factories CarFactory: Loaded new Car:Car: model=Audi model=A6 color=black serial=1 owner= CarFactory: Loaded new Car:Car: model=Audi model=A8 color=yellow serial=2 owner= CarFactory: Loaded new Car:Car: model=Audi model=A8 color=yellow serial=3 owner= CarFactory: Loaded new Car:Car: model=Audi model=A8 color=pink serial=4 owner= CarFactory: Loaded new Car:Car: model=BMW model=528i color=fjordgrau serial=1 owner= CarFactory: Loaded new Car:Car: model=BMW model=750Li color=articsilber serial=2 owner= CarFactory: Loaded new Car:Car: model=BMW model=528i color=applegreen serial=3 owner= CarFactory: Loaded new Car:Car: model=BMW model=528i color=sunblue serial=5 owner= CarFactory: Loaded new Car:Car: model=Volkswagen model=Golf TDI color=black serial=1000000 owner= CarFactory: Loaded new Car:Car: model=Volkswagen model=Golf CL color=darkred serial=1000001 owner= CarFactory: Loaded new Car:Car: model=Volkswagen model=Golf TDI color=deep space b serial=1000002 owner= Registring Car Factories Client Side The client programs are started by simply running CarSales as shown in the command line: % java CarSales CarSales calls a lookup method to obtain references to remote objects. Once obtained, these references are used to invoke various methods defined in CarFactory and implemented in CarFactoryImpl. The window shown in Figure 10-21 appears on the screen, displaying a trace of the different actions the client performs.
As soon as the client launches, the RMI server logs all the actions it performs on behalf of the client. CarFactory Audi: request for all cars. 4 returned. CarFactory BMW: request for all cars. 4 returned. CarFactory Volkswagen: request for all cars. 3 returned. CarFactory Audi: request for all cars. 4 returned. CarFactory: Created new Car:Car: model=Audi model=A8 color=orange serial=5 owner=None CarFactory Audi: request for all cars. 5 returned. CarFactory: Deleted Car:CarImpl_Stub[RemoteStub [ref: [endpoint:[guadalajara:37065](remote),objID:[14]]]] CarFactory Audi: request for all cars. 4 returned.
|
![]() |
|