Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

C/C++

C++, Java, & Service-Oriented Architectures


The Java Web Service

Java web services are simple to build and use. To start, download the Java Web Service Developer Pack, available on Sun's Java web site at http://java.sun.com/ webservices/downloads. This package includes a complete version of the Apache Tomcat Servlet engine, along with the Apache SOAP classes and deployment tools. The Java trading system web service for this article is implemented as a Java servlet that can run within any Java servlet engine. However, the Tomcat Servlet engine serves as an excellent environment.

The TradingSystemServlet class handles each incoming HTTP SOAP request, maps the request to RMI calls into the TradingSystemImpl class, and returns the result as a SOAP response. Example 1 shows the portion of the servlet that parses the request in the SOAP message, and ultimately calls the appropriate trading system and portfolio manager routines.

Example 1: Parsing the request in the SOAP message.

String requestName = elem.getNodeName();
if ( requestName.equalsIgnoreCase("GetQuote")) {    
    ret = getQuote( nodes );
}
else if ( requestName.equalsIgnoreCase("Buy")) {    
    ret = buy( nodes );
    if ( ret.equalsIgnoreCase("success"))
        ret = addHolding( nodes );
}
else if ( requestName.equalsIgnoreCase("Sell")) {    
    ret = sell( nodes );
    if ( ret.equalsIgnoreCase("success"))
        ret = removeHolding( nodes );
}
else if ( requestName.equalsIgnoreCase("GetPosition")) {    
    ret = getPosition( nodes );
}

Example 2 shows how the servlet uses RMI to call into the TradingSystemImpl class. First, an attempt is made to find an object within the RMI Registry that implements the TradingSystemInterface. If successful, method calls can be made on the object.

Example 2: Servlet using RMI to call into the TradingSystemImpl class.

TradingSystemInterface tradingSystem;
try {
  Registry rmiRegistry = LocateRegistry.getRegistry();
  tradingSystem = (TradingSystemInterface)
      rmiRegistry.lookup("TradingSystem");
} 
catch ( Exception e ) { 
}
 ...
// buy 10 shares of IBM stock
tradingSystem.Buy("IBM", 10); 

// add the new holding to the portfolio
tradingSystem.AddHolding("IBM", 10);

The code to read an incoming SOAP message is implemented within the servlet's doPost method (Listing Six). First, an instance of a DocumentBuilder class—implemented in the org.apache.soap.xml.XMLParserUtils library—is used to parse the incoming request XML into a DOM object. Next, the SOAP Envelope, which contains the SOAP message header and body, is extracted from the DOM. Finally, the SOAP body itself is extracted via a call to env.getBody.

Listing Six

public void doPost( HttpServletRequest request, HttpServletResponse response )
    throws IOException, ServletException
{
    try {
        String ret = "";
        // Read the request in as an XML string
        BufferedReader br = request.getReader() ;
        DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
        Document doc = xdb.parse( new InputSource(br) );

        // Get the SOAP envelope, which  contains the header and body
        Envelope env = Envelope.unmarshall( doc.getDocumentElement() );

        // Get the SOAP body, and create a Vector of body entries
        Body body = env.getBody();
        Vector bodyEntries = body.getBodyEntries();
		        
        // For the XML we're expecting, the body's 
        // root element should be the method name
        Enumeration e = bodyEntries.elements();
        Element elem = (Element)e.nextElement();

        // The child nodes of the root are the parameters
        NodeList nodes = elem.getChildNodes();
				
        // Get the method request name
        String requestName = elem.getNodeName();

        // Handle request
        ...

        // Send the response to the call
        sendSOAPResponse(requestName, ret, response);
    }
    catch ( Exception e ) {
        e.printStackTrace();
    }
}

The body contains the actual method name to call, and its parameters, which are extracted from the SOAP body by iterating through the DOM structure. Once the SOAP request is processed and the internal method calls are made, a SOAP response containing the method's return code is sent back to the caller.

A Java SOAP Client

With the C++ trading system and portfolio manager exposed as a web service, any SOAP-enabled client can use them, regardless of platform or language. The SOAP client included with the demo code for this article is a small Java application. The Java Web Services Developer Pack makes it as simple to build a SOAP client as it was to build our web service.

The sendSOAPMessage routine in Listing Seven shows how little code it takes to create and send an HTTP SOAP request and process a SOAP response.

Listing Seven

public void sendSOAPMessage(String hostURL, String filename)
{
    try {
        // Read and parse the XML to send 
        FileReader fr = new FileReader(filename);
        DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
        Document doc = xdb.parse(new InputSource(fr));
            
        // create the SOAP Envelope and Body
        Envelope env = new Envelope();
        Vector bodyElems = new Vector();
        bodyElems.add( doc.getDocumentElement() );
        Body body = new Body();
        body.setBodyEntries( bodyElems );
        env.setBody( body );
            
        // create SOAP message and send it
        org.apache.soap.messaging.Message msg = 
            new org.apache.soap.messaging.Message();
        msg.send(new java.net.URL(hostURL), URI, env);

        // get SOAP response
        SOAPTransport st = msg.getSOAPTransport();
        BufferedReader br = st.receive();
            
        System.out.println("\r\nSOAP Server response:");
        String line = br.readLine();
        while ( line != null ) {
            System.out.println(line);
            line = br.readLine();
        }
    }
    catch ( Exception e ) {
        e.printStackTrace();
    }
}

The client code resembles the SOAP code from the servlet, and takes the following steps:

  1. Creates an XML DOM object by reading and parsing the XML from a file.
  2. Creates a SOAP Envelope and Body, and fills the Body with the entries from the DOM.
  3. Creates a SOAP Message, and sends the Envelope—with the Body—to the server.
  4. Receives the response by calling the receive method on the SOAPTransport object, which blocks until the server sends a response.

Other potential SOAP clients include those written in C#, C++, VB.NET, Python, Perl, or any language that supports parsing and assembling SOAP messages in some way.

Running the Sample Code

The sample code for this article is comprehensive, and is available at http://www.cuj.com/code/. Table 1 lists the components of the sample, along with the directory for each component.

Table 1: Sample application components.

Component Directory
C++/COM Trading System SOATrading\TradingSystem
C++ Portfolio Manager DLL SOATrading\PortfolioManager
Java Native Interface/C++ Code SOATrading\JNITradingSystem
Java RMI Code SOATrading\RMITradingSystem
Java Servlet/Web Service SOATrading\TradingSystemServlet
Java SOAP Client SOATrading\SOAPClient

The C++ trading system is implemented as an ATL/COM executable. The COM server must be registered on your computer by running the following command:

>TradingSystem -regserver

For the Java-based components, you need the following software downloads:

  • Java2 Standard Edition (J2SE), http://java.sun.com/j2se/.
  • Java2 Enterprise Edition (J2EE), http://java.sun.com/j2ee/.
  • Java Web Service Developer Pack, http://java.sun.com/webservices/.

The JNI code for the trading system is implemented as a C++ Windows DLL. This DLL, and the portfolio manager DLL, must both be placed in the SOATrading\JNITradingSystem directory when built.

The Java RMI server application comes with two batch files, one to compile the source code (build.bat) and another to run it (runrmi.bat). When runrmi.bat is executed, it starts the Java RMIRegistry tool and then launches the RMITradingSystem application. The application registers its TradingSystemImpl object with the RMI registry. Both batch files contain file paths that will most likely need to change to match the locations on your computer.

The Java servlet must be deployed on a servlet-enabled web server, such as Apache Tomcat, which can be downloaded at http:// www.apache.org/. The directions for deploying the trading system servlet can be found in the file Readme.txt, in the SOATrading\TradingSystemServlet directory.

Finally, executing getquote.bat, buy.bat, or sell.bat runs the Java SOAP client. Each batch file launches the Java application, passing the web server URL and the appropriate XML file as parameters. Each XML file contains the XML body for the SOAP request. You can change the stock name, and the quantities traded, by modifying the XML files.

Conclusion

Java and C++ can be integrated, and there are cases where it is beneficial to do so. In the scenario I presented here, the trading system and the portfolio manager have been integrated via a Java web service and are now language and platform independent. Prior to this, the C++ application would not have been available to clients other than COM clients on Windows. This is a big achievement, and no existing C++ code needed to be changed.


Eric Bruno has worked extensively in Java and C++ developing real-time trading and financial applications. He can be contacted at [email protected] or http://www.ericbruno .com/.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.