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.
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.
The 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.
The IDL compiler generates a directory HelloApp/HelloPackage that contains the following
exception class files:
cantReadFile.java
cantReadFileHelper.java
cantReadFileHolder.java
cantWriteFile.java
cantWriteFileHelper.java
cantWriteFileHolder.java
Use of these classes is illustrated in the implementation below.
// 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.
The HelloServant object receives ansychronous and
possibly simultaneous method requests at
runtime. Therefore, you should enclose all file IO code
in a synchronized clause.
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 (\).
Create source files as shown above.
Run idlj on the IDL file to
create stubs and skeletons:
idltojava -fall Hello.idl
Compile the .java files, including the stubs and skeletons:
javac *.java HelloApp/*.java
Make sure the name server is running:
tnameserv -ORBInitialPort 1050&
Start the Hello server:
java HelloServer -ORBInitialPort 1050
Run the Hello application client from a different shell than the
server:
java HelloClient "remember this message" -ORBInitialPort 1050