This section illustrates how to delegate to a CORBA server from a Web service. In order to run this example you need an ORB such as the Novell exteNd Messaging Platform ORB installed on your system. In order to keep this section brief and to the point, we'll implement a very simple calculator service.
The IDL interface for the calculator is shown below. It supports adding, subtracting, multiplying and dividing double precision numbers.
module corba { interface Calculator { | double add(in double x, in double y); | double subtract(in double x, in double y); | double multiply(in double x, in double y); | double divide(in double x, in double y); }; };
In order to generate CORBA stubs and skeletons for this interface, you need to run the
idl2java compiler. This compiler is part of the ORB tools and you can look at the
provided build file for an example of how to run it. Since the calculator is already defined
in the 'corba' module, the generated classes will go into that Java package. The compiled
class files should be stored into the WEB-INF/classes
directory as usual.
The implementation of the CORBA server is fairly straightforward: The server has a
main
method to bootstrap the server, and besides that an implementation of
the four methods from the IDL interface.
package corba; import java.io.FileOutputStream; public class CorbaServer extends _CalculatorImplBase { public static void main(String[] args) throws Exception { | org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); | CorbaServer CS = new CorbaServer(); | FileOutputStream fos = new FileOutputStream("calc.ior"); | fos.write(orb.object_to_string(CS).getBytes()); | fos.flush(); | fos.close(); | System.out.println("CORBA calculator ready ..."); | orb.run(); } public double add(double x, double y) { | return x + y; } public double subtract(double x, double y) { | return x - y; } public double multiply(double x, double y) { | return x * y; } public double divide(double x, double y) { | return x / y; } }
The main
method stores the IOR of the CORBA server into a file called
calc.ior
, which the Web service can load as part of its initialization.
A more sophisticated program might store the object reference for the CORBA server in
a naming service.
In order to expose the above server as a Web service, we need RMI for the calculator
service. Since the interfaces generated by the IDL compiler are not proper RMI, we create
a new interface, which is identical to the CORBA interface, but which extends
java.rmi.Remote
and where all methods throws java.rmi.RemoteException
.
You can conveniently use the java2rmi wizard
for converting a regular Java class or interface to RMI.
package corba; import java.rmi.Remote; import java.rmi.RemoteException; public interface Calc extends Remote { double add(double x, double y) throws RemoteException; double subtract(double x, double y) throws RemoteException; double multiply(double x, double y) throws RemoteException; double divide(double x, double y) throws RemoteException; }
At this point, we're back to using the Novell exteNd WSSDK. We create a Web service,
which loads the calc.ior
file in its init
method and delegates
to the resulting CORBA object in the four business methods:
package corba; import java.io.IOException; import java.io.FileInputStream; import javax.servlet.ServletException; public class CalcImpl extends Calc_ServiceSkeleton { private Calculator calculator; public void init() throws ServletException { | super.init(); | | try { | | String[] args = new String[0]; | | org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); | | FileInputStream fis = new FileInputStream("calc.ior"); | | byte[] b = new byte[fis.available()]; | | fis.read(b); | | String ior = new String(b); | | calculator = CalculatorHelper.narrow(orb.string_to_object(ior)); | | fis.close(); | } catch (IOException ex) { | | throw new ServletException(ex.getMessage()); | } } public double add(double x, double y) { | return calculator.add(x, y); } public double subtract(double x, double y) { | return calculator.subtract(x, y); } public double multiply(double x, double y) { | return calculator.multiply(x, y); } public double divide(double x, double y) { | return calculator.divide(x, y); } }
In order to deploy the Web service, you need to ensure that the ORB settings are correct. If the ORB is installed as a JRE extension, you can typically run without any additional settings. Please consult your ORB documentation for details.
The client is similiar to any other client we have written in this tutorial. It creates a stub from the generated service and invokes each of the four business methods:
package corba; import javax.xml.rpc.Stub; import javax.naming.InitialContext; public class Client { public static void main(String[] args) throws Exception { | // get the initial context | InitialContext ctx = new InitialContext(); | | // lookup the service for Hello | CalcService svc = (CalcService) | ctx.lookup("xmlrpc:soap:corba.CalcService"); | | // get the hello stub | Calc calc = (Calc) svc.getCalcPort(); | | // set the end point address | ((Stub)calc)._setProperty("javax.xml.rpc.service.endpoint.address", | args.length > 0 ? args[0] :"http://localhost:9090/corba"); | | System.out.println("2+3=" + calc.add(2,3)); | System.out.println("5-3=" + calc.subtract(5,3)); | System.out.println("2*3=" + calc.multiply(2,3)); | System.out.println("9/3=" + calc.divide(9,3)); } }
Please refer to the README for detailed instructions on compiling, deploying and running the example.
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.