Java IDL only supports transient objects - if an object's server process halts and restarts, the object reference becomes invalid. However, Example 2 illustrates how a transient object can store its state and re-initialize itself from this state each time the server is restarted.
The Example 2 server hosts a Hello object that stores a string in a file. You provide the string as a command line argument to the client program. The server Hello object "remembers" the string and returns it to the client the next time that the client is run, even if the server has been stopped and restarted.
Example 2 is identical to Example 1 except for the persistence enhancements. This page only discusses the code neccessary to these enhancements.
This page contains:
Instructions for compiling and running
the example are provided.
Interface Definition (
Hello.idl
)
module HelloApp { interface Hello { exception cantWriteFile{}; exception cantReadFile{}; string sayHello(in string message) raises (cantWriteFile); string lastMessage() raises (cantReadFile); }; };Because the Hello object reads from and writes to a file, you will need to throw Java language exceptions. (See Implementing the Server below). The Hello interface must define and raise exceptions in order to generate the appropriate skeleton definitions.
sayHello
method has been modified to take a string argument,
which will be stored in a file at runtime. A lastMessage
method has been added to return this stored string to the client.HelloApp/
HelloPackage
that contains the following
exception class files:
HelloServer.java
)// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; class HelloServant extends _HelloImplBase { public String sayHello(String msg) throws HelloApp.HelloPackage.cantWriteFile { try { synchronized(this) { File helloFile = new File("helloStorage.txt"); FileOutputStream fos = new FileOutputStream(helloFile); byte[] buf = new byte[msg.length()]; msg.getBytes(0, msg.length(), buf, 0); fos.write(buf); fos.close(); } } catch(Exception e) { throw new HelloApp.HelloPackage.cantWriteFile(); } return "\nHello world !!\n"; } public String lastMessage() throws HelloApp.HelloPackage.cantReadFile { try { synchronized(this) { File helloFile = new File("helloStorage.txt"); FileInputStream fis = new FileInputStream(helloFile); byte[] buf = new byte[1000]; int n = fis.read(buf); String lastmsg = new String(buf); fis.close(); return lastmsg; } } catch(Exception e) { throw new HelloApp.HelloPackage.cantReadFile(); } } } public class HelloServer { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // create servant and register it with the ORB HelloServant helloRef = new HelloServant(); orb.connect(helloRef); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // bind the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; ncRef.rebind(path, helloRef); // wait for invocations from clients java.lang.Object sync = new java.lang.Object(); synchronized (sync) { sync.wait(); } } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } }The
sayHello
and lastMessage
method implementations
throw the exceptions defined in the IDL file. These methods must throw file
IO exceptions or the Java language compiler issues warnings and errors.HelloServant
object receives ansychronous and
possibly simultaneous method requests at
runtime. Therefore, you should enclose all file IO code
in a synchronized
clause.HelloServer.main
.
HelloClient.java
)// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; public class HelloClient { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // resolve the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); // call the Hello server object and print results String oldhello = helloRef.lastMessage(); System.out.println(oldhello); String hello = helloRef.sayHello(args[0]); System.out.println(hello); } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } }This client retrieves the stored message via
lastMessage
and stores the new message via an argument to sayHello
.
The following instructions assume you can use port 1050 for the Java IDL name server. Substitute a different port if necessary. Note that for ports below 1024, you need root access on UNIX machines, and administrator privileges on Windows95 and NT. Note also that the instructions use a slash (/) for path names. Windows95 and NT users should subtitute a backslash (\).
idltojava Hello.idl
javac *.java HelloApp/*.java
tnameserv -ORBInitialPort 1050&
java HelloServer -ORBInitialPort 1050
java HelloClient "remember this message" -ORBInitialPort 1050
Home |
Copyright © 1995-98 Sun Microsystems, Inc. All Rights Reserved.