|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 5
As you will see, the three implementations of the sender and receiver described here are implemented as Xbeans. An Xbean is a software component that takes XML as input, processes it, and then passes XML on to the next Xbean. Xbeans consume and produce XML as DOM documents. That is, the data passed to Xbeans are not strings that need to be parsed by an XML parser; rather, they make up an already parsed document object accessed
via the W3C standard DOM API. Figure 2 illustrates an Xbean.

Figure 2. Xbeans consume and produce XML as DOM documents
Xbeans are JavaBeans, which support the packaging, reuse, connection, and customization of Java code. With the appropriate set of
Xbeans and a JavaBean design tool, you can build useful distributed applications with little or no programming.
Xbeans are inspired by IBM's XML Productivity Kit for Java. They are focused on distributed applications and thus have a modified
interface. Xbeans are freely available through the Xbeans.org open source project.
Now I'll describe for you the three different approaches to implementing the sender and the receiver, complete with Java code. After presenting them, I'll analyze the performance of each approach.
The first approach is to simply send the XML as text to the Web server on a remote machine. The sender must convert the DOM representation of the XML into text and communicate the text to the receiver. Then, the receiver must convert the text back to the DOM representation. Figure 3 illustrates this approach.

Figure 3. A sender and receiver sending XML text via HTTP
The following code fragment uses HTTP to implement the sender. The code uses the DOMWriter class in IBM's Productivity Kit for Java to convert the DOM representation to a textual XML representation. See Resources for the complete code.
public void documentReady(DOMEvent evt)
throws XbeansException {
try {
URL receiver = new URL(getRemoteURL());
URLConnection receiverConnection =
receiver.openConnection();
receiverConnection.setDoOutput(true);
// open an output stream to the sender and
// send the xml in text form
OutputStream out =
receiverConnection.getOutputStream();
DOMWriter writer = new DOMWriter();
writer.setPrintWriter(new PrintWriter(out));
writer.documentReady(
new com.ibm.xml.xpk4j.dom.DOMEvent(
this,evt.getDocument()));
out.close();
// open an input stream for result
BufferedReader in =
new BufferedReader(new InputStreamReader(
receiverConnection.getInputStream()));
// process result: "OK" indicates success,
// "Exception" indicates input stream contains
// serialized exception.
...
in.close();
} catch (Throwable e) {
e.printStackTrace(System.err);
}
}
Note that the above documentReady() method uses the remoteURL property to get the URL of the CGI script on the server.
To be compatible with HTTP, the CGI script class wraps the receiver's output with the string "Content-type: text/html". The script then invokes the Java Virtual Machine and the receiverMain() on the server. Here's the code for the CGI script on the server:
#!/bin/sh echo "Content-type: text/html" echo /usr/local/bin/java org.xbeans.communication.http.receiverMain 2>&1
The main() method simply instantiates the receiver and invokes receiveDocument() on the receiver.
import org.xbeans.communication.stdio.receiver.*;
public class receiverMain { static Bean theReceiver = new Bean();
public static void main(String[] args) { theReceiver.receiveDocument(); } }
Finally, here's a code fragment from receiveDocument() to recreate the DOM representation and pass it on for further processing. This code depends on IBM's XML parser.
// Create a parser
DOMParser parser = new DOMParser();
// Invoke the parser.
try {
parser.parse(new InputSource(System.in));
} catch (Throwable e) {
throw new XbeansException(
"",
"receiver",
"io error parsing incoming document",
"io error parsing incoming document "+e
);
}
// Pass the document on to the next bean
DOMListener.documentReady(new DOMEvent(this,parser.getDocument()));
The second approach uses Java RMI and DOM serialization to transfer the DOM from the sender to the receiver. Figure 4 illustrates this approach.

Figure 4. Communicating a serialized DOM using Java RMI
The following code implements the sender using Java RMI to communicate with the receiver.
public void documentReady(DOMEvent evt)
throws XbeansException {
if (DOMListener==null) {
try {
DOMListener =
(DOMListener)Naming.lookup(getReceiverName());
} catch (Exception e) {
throw new XbeansException(
evt.getDocument().getNodeName(),
"sender",
"error obtaining remote receiver",
"The name may be wrong or the network may be down."
);
}
}
DOMListener.documentReady(evt);
}
The following code implements the receiver using Java RMI. The setName() method exports the receiver to the RMI registry and the documentReady() method simply passes on the received document to the next component.
public void setReceiverName(String newName) {
try {
if (receiverName!=null) Naming.unbind(receiverName);
receiverName = newName;
Naming.rebind(receiverName, this );
} catch( Exception e ) {
System.out.println( e );
}
}
public void documentReady(Document incomingDocument) throws RemoteException, XbeansException {
if (DOMListener==null) {
throw new XbeansException(
incomingDocument.getNodeName(),
"rmiReceiver",
"next component not established",
"The component needs to be configured."
);
}
DOMListener.documentReady(new DOMEvent(this,incomingDocument));
}
The third approach uses CORBA-IIOP (CORBA over Internet Inter-ORB Protocol) as a transport. The Object Management Group (OMG) currently has a request for proposal (Resources) for extending the Interface Definition Language (IDL) to include an XML data type. Thus, in the future, CORBA products will be able to transmit XML natively. Figure 5 illustrates this approach.

Figure 5. Transmitting XML natively using CORBA
Since today's CORBA products cannot represent XML natively, the code presented here uses Java serialization of the DOM and communicates it to the receiver as a sequence of octets. It is very similar to the Java RMI approach. The only difference is that the distributed object infrastructure is provided by CORBA systems.
The following OMG IDL gives the interface between the CORBA implementation of the sender and the receiver:
exception RemoteReceiverException {
string remoteIdentifier;
string documentName;
string componentName;
string message;
string moreMessage;
};
typedef sequence<octet> byteArray;
interface XMLReceiver {
void documentReady(in byteArray serializedDocument)
raises(RemoteReceiverException);
};
The following code implements the sender using Java serialization of the DOM and CORBA:
public void documentReady(DOMEvent evt)
throws XbeansException {
Document documentToSend = evt.getDocument();
try {
ByteArrayOutputStream bastream =
new ByteArrayOutputStream();
ObjectOutputStream p =
new ObjectOutputStream(bastream);
p.writeObject(documentToSend);
p.flush();
org.omg.CORBA.ORB orb =
org.omg.CORBA.ORB.init(
new String[0],
System.getProperties());
XMLReceiver receiver =
urlToObject(orb,getReceiverURL());
receiver.documentReady(bastream.toByteArray());
} catch (RemoteReceiverException rre) {
throw new XbeansException(
rre.remoteIdentifier,
rre.documentName,
rre.componentName,
rre.message,
rre.moreMessage
);
} catch (Throwable e) {
throw new XbeansException(
"",
"sender",
"error sending document "+e,
"error sending document "+e
);
}
}
The following code implements the receiver using Java serialization of the DOM and CORBA:
public void documentReady(byte[] serializedDocument)
throws RemoteReceiverException {
// Deserialize the byte stream.
ByteArrayInputStream bais =
new ByteArrayInputStream(serializedDocument);
Document theDocument;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
theDocument = (Document)ois.readObject();
} catch(Throwable e) {
throw new RemoteReceiverException(
corbaName,
"incoming document",
"receiver",
"error deserializing document",
"error deserializing document"+e
);
}
// Pass on the document to the listener
try {
local.DOMListener.documentReady(
new DOMEvent(this,theDocument));
} catch (XbeansException xbe) {
throw new RemoteReceiverException(
xbe.remoteIdentifier(),
xbe.documentName(),
xbe.componentName(),
xbe.message(),
xbe.moreMessage()
);
}
}
Server-side Java: Read the whole series -archived on JavaWorld