(See horb/examples/interfaceCall and horb/examples/interfaceCall2 for example code.)
In the previous section we accessed the server object locally then remotely. While the previous examples are accomplished with separate sets of code, this section will combine both local and remote methods into one program. Here's an example of creating two server objects together:
// a fragment of Client.java Server server = new Server(); // local object Server_Proxy server2 = new Server_Proxy(url); // remote object
After creating two server objects we can imagine a situation where it is necessary to call a method display() to display results for each object. The method sub takes one argument, a reference to a server object. How do we write this method?
// a fragment of Client.java void display(Server server) { // for local object . . . } void display(Server_Proxy server) { // for remote object . . . }
Because class Server and class Server_Proxy are different classes, we must define two foo() methods for each. That's not very elegant. In other cases we might want to store the references into instance variables of the same type. For such purposes, HORB supports the remote object call through an interface definition. The interface definition of the Server object is:
// Server.java package horb.examples.interfaceCall; interface Server { String greeting(String name); }
Method greeting() may throw above two exceptions when it is called remotely.
The HORBC compiler generates class Server_Proxy and class Server_Skeleton
from this interface. Next, we have to supply the implementation of the
interface.
// Server_Impl.java package horb.examples.interfaceCall; class Server_Impl implements Server { public String greeting(String name) { return "Hello, " + name + "!"; } }
The names of implementation classes must be identical to the interface names, plus the ending "_Impl", Server_Impl in this case. The Server_Skeleton object calls Server_Impl when a client calls the method through the interface. Since class Server_Proxy also implements interface Server, a reference to a local object and a reference to a remote object are treated as the same type, Server.
Let's write an accompanying client class. In this example we create a local and a remote server object and treat them as the same type. Hence, the client class has only one display() method.
// Client.java package horb.examples.interfaceCall; import horb.orb.*; class Client { public static void main(String argv[]) { Server server1 = new Server_Impl(); String host = (argv.length == 1) ? argv[0] : "-"; HorbURL url = new HorbURL("horb://"+host); Server server2 = new Server_Proxy(url); display(server1, "Baby"); display(server2, "World"); } static void display(Server server, String name) { String result = server.greeting(name); System.out.println(result); } }
The order of compilation is a bit more complicated than before. The class Server_Proxy and class Server_Skeleton are generated from interface Server. The class Server_Impl and class Client depend on the interface Server. Thus, the order of compilation is:
C:> horbc Server.java C:> horbc -c Server_Impl.java Client.java
Remember, you can use horbc -c command instead of javac command. Now we have Server.class, Server_Proxy.class, Server_Skeleton.class, Server_Impl.class, and Client.class. To run these classes:
C:> horb -v (in another window) C:> java horb.examples.interfaceCall.Client Hello, Baby! Hello, World!
As in the last example in the previous section, we can run the server object on a separate server machine. Copy classes you compiled to the server machine.
S:> horb -ve (on machine serverA) C:> java horb.examples.interfaceCall.Client serverA Hello, Baby! Hello, World!See horb/examples/interfaceCall2 for another example of use of interface. This example is a bit smarter than the above example.