Chapter 3 Tutorial: C++ Components and C++ Clients


Creating the application

To create and run the sample application:

  1. Start the Jaguar server and Jaguar Manager
  2. Define a package, component, and method
  3. Generate stubs, skeletons, and implementation templates
  4. Write the server-side code
  5. Write the client-side code
  6. Compile the client executable
  7. Run the client executable

Start the Jaguar server and Jaguar Manager

Steps Start the Jaguar server:

  1. If the Jaguar server is not already running, follow the instructions under "Starting Jaguar" to start the server.


Steps Start Jaguar Manager:

  1. If Jaguar Manager is not already running, start it as described in "Starting Jaguar Manager and Security Manager".


Define a package, component, and method

This section shows you how to use Jaguar Manager to create the package, component, and method for the sample application.

For complete information on configuring packages, components, and methods, see the Jaguar CTS Programmer's Guide.

Define a new package

In Jaguar, a package is a unit of deployment for a group of components that perform related tasks. A component must be installed in a package before it can be instantiated by applications.

Steps Create the Tutorial package if it does not exist:

  1. Navigate to:

    Jaguar Manager | Servers | Jaguar

  2. In the right panel, click Packages. If the Tutorial package is displayed, skip to the next section, "Define and install a new component".

  3. Select File | Install Package.

    In the Package wizard, select Create and Install a New Package.

    For the package name, enter Tutorial .

  4. Click Create New Package.

    You see the Package Properties window.

  5. Click OK.

    When you click on the Installed Packages expansion sign, it now includes Tutorial.


Define and install a new component

Steps Using Jaguar Manager, define a new component for the package you just created:

  1. Click on the Tutorial package.

  2. Select File | Install Component.

  3. In the Component wizard, select Create and Install a New Component.

    For the component name, enter CPPArithmetic .

  4. Click Create New Component.

  5. Select the Define New Component check box. Click OK.

    You see the Component Properties window.

  6. Select the General tab. Fill in the fields as follows:

    Field

    Value

    Description

    Tutorial C++ component

    Codeset

    Server's Codeset
    (default)

    IDL Interface

    Tutorial::CPPArithmetic
    (default)

    Component Type

    C++

    DLL Name

    libCPPArithmetic.dll

    C++ Class

    CPPArithmeticImpl

  7. Leave the remaining fields at their default settings.

  8. Click OK.


Define the multiply method

Steps After the component is defined, define methods for it that the client will call:

  1. Expand the Tutorial package. Select the CPPArithmetic component.

  2. Select File | New Method.

  3. Assign the name multiply to the method.

  4. Click Create New Method.

    You see the Method Properties window.

  5. In the Return field, select double as the method's return type.

  6. Beneath the empty parameter list, click Add to add a parameter. In the New Parameter dialog:

  7. Click OK to close the New Parameter dialog box.

  8. Repeat steps 6 and 7 to add a second parameter named m2 and with a type of double .

  9. Click OK to close the Method Properties dialog box.

  10. At this point, Jaguar Manager has created an IDL interface for the component with a multiply method. You can view the generated IDL interface as follows:

    1. Expand the Modules folder in Jaguar Manager.

    2. Right-click the icon for the Tutorial module.

    3. Choose Edit Module IDL ... from the pop-up menu. The module's definition displays in the IDL Editor window.

    4. View the IDL definitions for the module, interface, and method that you created earlier.

    5. Close the IDL Editor window by choosing File | Exit from the menu.



For more information on defining methods and parameters, refer to Chapter 4, "Defining Component Interfaces" in the Jaguar CTS Programmer's Guide.

Generate stubs, skeletons, and implementation templates

Once you have created the package, component, and methods, you need to generate the stub files for the component. The client-side applet uses the stubs to invoke the server-side component methods.

Steps To generate the stubs and skeletons

  1. Click on the Tutorial package and select the CPPArithmetic component.

  2. Select File | Generate Stubs/Skeletons.

  3. Select Generate Stubs, then check C++ Stubs. In the C/C++ Code Base field, enter the path to the Jaguar include subdirectory--for example:
    %JAGUAR%\include .

  4. Unselect Generate Java Stubs.

  5. Select Generate Skeletons.

  6. Under Skeletons in the C/C++ Code Base field, type the full path to a subdirectory where you will create the component source files--for example:
    d:\jagtut


  7. Click Generate.


Write the server-side code

Steps To write the server-side code:

  1. Navigate to the directory that you specified for C/C++ Code Base in the skeleton generation options, then navigate to the Tutorial/CPPArithmetic subdirectory. You should see the following files:

  2. Rename the implementation files to CPPArithmeticImpl.hpp and CPPArithmeticImpl.cpp (delete the .new extension).

  3. Open CPPArithmeticImpl.cpp in a text editor, then find the definition of the multiply method. Change the definition so that it matches the one below:
    CORBA::Double CPPArithmeticImpl::multiply
    (CORBA::Double m1,
    CORBA::Double m2)
    {
    CORBA::Double result;
    result = m1 * m2;
    return result;
    }


  4. Save your changes.

  5. Rename make.nt to Makefile, then open Makefile in a text editor. Find the definition of the ODBCHOME macro:
    ODBCHOME=d:\msdev


    Change the ODBCHOME definition to match the directory where you have installed Microsoft Visual C++. Save your changes.

    Build the DLL for the component by running nmake (no arguments are required). You should see a new file called libCPPArithmetic.dll. Copy this file to the Jaguar cpplib subdirectory. If nmake fails, verify that you have renamed the .cpp and .hpp implementation files with the expected file names, and that you have applied the correct edits to CPPArithmeticImpl.cpp.


Write the client-side code

Create the source file for the sample C++ client, arith.cpp. You can find a copy of arith.cpp in the html/docs/tutorial subdirectory of your Jaguar installation. Here is the source for arith.cpp:

/*
** arith.cpp -- Example C++ client for the Jaguar C++
** tutorial.
**
** This program connects to the Jaguar naming server,
** creates an instance of the Tutorial/CPPArithmetic
** component, and invokes the multiply method.
**
** Usage:
** arith [ -ORBNameServiceURL iiop://<host>:<port>/<context> ]
**
** The ORBNameServiceURL must be specified unless you specify
** the URL by setting the JAG_NAMESERVICEURL environment
** variable. The URL components are as follows:
**
** <host> is the Jaguar naming server host name.
**
** <port> is the naming server's IIOP port (9000 in the
** default configuration.
**
** <initial-context> is the naming server's initial
** context, for example, US/Sybase/Jaguar/Pubs.
** In the default configuration, the context
** is an empty string.
**
** If you are using the default configuration, your
** component's name server is the Jaguar server where it is
** installed, and the initial context is null. In this
** case, enter the URL as
** iiop://<host>:9000
*/

#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <Jaguar.hpp>
#include <SessionManager.hpp>
#include <CosNaming.hpp>
#include <Tutorial.hpp> // Stubs for interfaces in Tutorial
// IDL module.

int main(int argc, char** argv)
{
const char *usage =
"Usage:\n\tarith \
-ORBNameServiceURL iiop://<host>:<port>/<initial-context>\n";
const char *tutorial_help =
"Check Jaguar Manager and verify that the"
"Tutorial/CPPArithmetic component exists "
"and that it implements the "
"Tutorial::CPPArithmetic IDL interface.";

const char *component_name = "Tutorial/CPPArithmetic";

try {

cout << "Creating Jaguar session\n\n";

// Initialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, 0);

// Obtain the CORBA CosNaming initial naming context
// that we will use to resolve objects by name. The
// ORB retrieves the naming server address from
// command line arguments or the environment.

CORBA::Object_var obj =
orb->resolve_initial_references("NameService");
CosNaming::NamingContext_var nc =
CosNaming::NamingContext::_narrow(obj);
if (CORBA::is_nil(nc)) {
cout << "Error: Null NamingContext instance. Exiting.";
return -1;
}

// Build a CosNaming::Name object that contains the
// name of the tutorial component, Tutorial/CPPArithmetic

name[0].id = CORBA::string_dup( component_name );
name[0].kind = CORBA::string_dup( "" );

// Obtain a factory for component instances by
// resolving the component name
cout <<
"Creating component instance for "
<< component_name << "\n\n";
obj = nc->resolve(name);
SessionManager::Factory_var arithFactory =
SessionManager::Factory::_narrow(obj);

if (CORBA::is_nil(arithFactory)) {
cout << "ERROR: Null component factory. "
<< tutorial_help ;
return -1;
}

// Use the factory to create an instance, passing the
// username and password for authorization

Tutorial::CPPArithmetic_var arith =
Tutorial::CPPArithmetic::_narrow(
arithFactory->create("Guest", "GuestPassword") );

// Verify that we really have an instance.
if (CORBA::is_nil(arith)) {
cout << "ERROR: Null component instance. "
<< tutorial_help ;
return -1;
}

// Call the multiply method.
cout << "Multiplying ...\n\n";
CORBA::Double m1 = (CORBA::Double)3.1;
CORBA::Double m2 = (CORBA::Double)2.5;
CORBA::Double result = arith->multiply(m1, m2);

cout << (double)m1 << " * " << (double)m2
<< " = " << (double)result
<< "\n\n";

}

// Explicitly catch exceptions that can occur due to user
// error, and print a generic error message for any other
// CORBA system exception.

// Requested object (component) does not exist.
catch (CosNaming::NamingContext::NotFound &nf)
{
cout << "Error: Component " << component_name
<< " not found. "
<< "Verify that the component has been created "
<< "properly in Jaguar Manager. "
<< "Also check the server log file for additional "
<< "information.";
}

// Authentication or authorization failure.
catch ( CORBA::NO_PERMISSION npe )
{
cout << "Error: CORBA:: NO_PERMISSION exception. "
<< "Check whether login authentication is enabled "
<< "for your server and whether the component has "
<< "restricted access."
}

// Invalid object reference.
catch ( CORBA::INV_OBJREF cio )
{
cout << "Error: CORBA INV_OBJREF exception.";
}

// Communication failure. Server could be down or URL's
// port value could be wrong.
catch ( CORBA::COMM_FAILURE ccf )
{
cout << "Error: CORBA COMM_FAILURE exception. "
<< "Check that the specified Jaguar host "
<< "and IIOP port number are correct and "
<< "that the server is running.\n"
<< usage;
}
// Requested object (component) does not exist.
catch ( CORBA::OBJECT_NOT_EXIST cone )
{
cout << "Error: CORBA OBJECT_NOT_EXIST exception. "
<< "Check the server log file for more "
<< "information. Also verify that the "
<< component_name
<< " component has been created properly in "
<< "Jaguar Manager.\n";
}
// Anything else.
catch ( CORBA::OBJ_ADAPTER )
{
cout << "Error: CORBA::OBJ_ADAPTER \n";
}
catch ( CORBA::SystemException cse )
{
cout << "Error: CORBA System Exception. Check that "
"the Jaguar hostname and IIOP port are "
<< "specified correctly, and check the server's"
<< " error log for more information.\n"
<< usage;
}

return 0;
}

Compile the client executable

To compile arith.cpp, on Windows, run this batch file:

SETLOCAL
set INCLUDE=.;%JAGUAR%\include;%INCLUDE%
set LIB=%JAGUAR%\lib;%LIB%
cl /W3 /nologo /DWIN32 /Gd /GX -c arith.cpp
set SYSLIBS=kernel32.lib advapi32.lib
link /MAP /out:arith.exe arith.obj libjcc.lib %SYSLIBS%
ENDLOCAL

Run the client executable

If you have not restarted the Jaguar server since creating the CPPArithmetic component, do so now before running the client program.

Note   Classpath conflicts on development workstations If you are running the sample client on a machine where EAServer has been installed, you must configure your browser to eliminate conflicts between Jaguar classes that are downloaded with the applet and classes that are loaded from the local classpath. See "Configuring browsers to run applets on development machines" for instructions.

Run the executable, specifying the Jaguar server host name and IIOP port number on the command line as follows:

arith -ORBNameServiceURL iiop://host:iiop-port

For example:

arith -ORBNameServiceURL iiop://myhost:9000

If everything is working, arith prints the results from the invocation of the multiply method. If not, check the error text printed on the console where you ran the client, and check for error messages in the server log file.

 


Copyright © 2000 Sybase, Inc. All rights reserved.