|
|
This topic includes the following sections:
Table 4-1 outlines the development process for WLE CORBA applications.
Overview of the Development Process for WLE CORBA Applications
Step |
Description |
---|---|
The steps in the development process are described in the following sections.
Figure 4-1 illustrates the process for developing WLE CORBA applications.
Throughout this topic, the Simpapp sample application is used to demonstrate the development steps. C++ and Java versions of the Simpapp sample application are available.
The server application in the Simpapp sample application provides an implementation of a CORBA object that has the following two methods:
Figure 4-1 Development Process for WLE CORBA Applications
The Simpapp Sample Application
Figure 4-2 illustrates how the Simpapp sample application works.
The source files for the C++ and Java versions of the Simpapp sample application are located in the \samples\corba\simpapp and \samples\corba\simpap_java directories of the WLE software. Instructions for building and running the Simpapp sample applications are in the readme files in the directories. For instructions for building and running the C++ and Java Simpapp sample applications, see Samples in the WebLogic Enterprise online documentation.
Note: The Simpapp sample applications demonstrate building C++ client and server applications and Java client and server applications. For information about building a simple ActiveX client application, see the Basic sample application in the WebLogic Enterprise online documentation.
The WLE product offers a suite of sample applications that demonstrate and aid in the development of WLE CORBA applications. For an overview of the available sample applications, see Samples in the WebLogic Enterprise online documentation.
The first step in writing a WLE application is to specify all of the CORBA interfaces and their methods using the Object Management Group (OMG) Interface Definition Language (IDL). An interface definition written in OMG IDL completely defines the CORBA interface and fully specifies each operation's arguments. OMG IDL is a purely declarative language. This means that it contains no implementation details. Operations specified in OMG IDL can be written in and invoked from any language that provides CORBA bindings.
The Simpapp sample application implements the CORBA interfaces listed in Table 4-2.
Interface |
Description |
Operation |
---|---|---|
Listing 4-1 shows the simple.idl
file that defines the CORBA interfaces in the Simpapp sample application. The same OMG IDL file is used by both the C++ and Java Simpapp sample applications.
Listing 4-1
OMG IDL Code for the Simpapp Sample Application
#pragma prefix "beasys.com" interface Simple //Convert a string to upper case (in place) interface SimpleFactory The interface specification defined in OMG IDL is used by the IDL compiler to generate client stubs for the client application, and skeletons for the server application. The client stubs are used by the client application for all operation invocations. You use the skeleton, along with the code you write, to create the server application that implements the CORBA objects.
During the development process, use one of the following commands to compile the OMG IDL file and produce client stubs and skeletons for WLE client and server applications:
{
//Convert a string to lower case (return a new string)
string to_lower(in string val);
void to_upper(inout string val);
};
{
Simple find_simple();
};Step 2: Generate client stubs and skeletons.
Table 4-3 lists the files that are created by the idl
command.
Table 4-3 Files Created by the IDL Command
Table 4-4 lists the files that are created by the m3idltojava
command.
Table 4-4 Files Created by the m3idltojava
Command
The WLE software supports C++ and Java server applications. The steps for creating server applications are:
Step 3: Write the server application.
After you compile the OMG IDL file, you need to write methods that implement the operations for each interface in the file. An implementation file contains the following:
Within the activate_object () and deactivate_object() methods, you write code that performs any particular steps related to activating or deactivating the object. For more information, see Creating CORBA C++ Server Applications and Creating CORBA Java Server Applications
in the WebLogic Enterprise online documentation.
You can write the implementation file by hand. However, both the idl
and m3idltojava
commands have an option that generates a template for implementation files.
Listing 4-2 includes the C++ implementation of the Simple and SimpleFactory interfaces in the Simpapp sample application.
Listing 4-2
C++ Implementation of the Simple and SimpleFactory Interfaces
// Implementation of the Simple_i::to_lower method which converts // Implementation of the Simple_i::to_upper method which converts Listing 4-3 includes the Java implementation of the Simple interface from the Simpapp sample application.
Listing 4-3
Java Implementation of the Simple Interface
import com.beasys.Tobj.TP; Listing 4-4 includes the Java implementation of the SimpleFactory interface from the Simpapp sample application.
Listing 4-4
Java Implementation of the SimpleFactory Interface
import com.beasys.Tobj.TP; public Simple find_simple() The Server object performs the following tasks:
// a string to lower case.
char* Simple_i::to_lower(const char* value)
{
CORBA::String_var var_lower = CORBA::string_dup(value);
for (char* ptr = v_lower; ptr && *ptr; ptr++) {
*ptr = tolower(*ptr);
}
return var_lower._retn();
}
// a string to upper case.
void Simple_i::to_upper(char*& valuel)
{
CORBA::String_var var_upper = value;
var_upper = CORBA::string_dup(var_upper.in());
for (char* ptr = var_upper; ptr && *ptr; ptr++) {
*ptr = toupper(*ptr);
}
value = var_upper._retn();
}
// Implementation of the SimpleFactory_i::find_simple method which
// creates an object reference to a Simple object.
Simple_ptr SimpleFactory_i::find_simple()
{
CORBA::Object_var var_simple_oref =
TP::create_object_reference(
_tc_Simple->id(),
"simple",
CORBA::NVList::_nil()
);
}
/**
*The SimpleImpl class implements the to_upper and to_lower
*methods.
*/
public class SimpleImpl extends _SimpleImplBase
{
/*Converts a string to upper case.*/
public void to_upper(org.omg.CORBA.StringHolder data)
{
if (data.value == null)
return;
data.value = data.value.toUpperCase();
return;
}
/*Converts a string to lower case.*/
public String to_lower(String data)
{
if (data == null)
return null;
return data.toLowerCase();
}
}
/**
*The SimpleFactoryImpl class provides code to create the Simple *object.
*/
public class SimpleFactoryImpl extends _SimpleFactoryImplBase
{
/*Create an object reference to a Simple object*/
{
org.omg.CORBA.Object simple_oref =
TP.create_object_reference(
SimpleHelper.id(), //Repository ID
"simple", //object id
null //routing criteria
);
//Send back the narrowed reference
return SimpleHelper.narrow(simple_oref);
};
};
}; Creating the Server Object
In C++ server applications, the Server object is already instantiated and a header file for the Server object is available. You implement methods that initialize and release the server application, and, if desired, create servant objects.
Listing 4-5 includes the C++ code from the Simpapp sample application for the Server object.
Listing 4-5
C++ Server Object
static CORBA::Object_var static_var_factory_reference; // Method to start up the server In Java server applications, you implement the Server object by creating a new class that derives from the com.beasys.Tobj.Server
class and overrides the initialize()
and release()
methods. In the server application code, you can also write a public default constructor for the Server object. When creating Java server applications, you identify the name of the Server object in the Server Description File.
The create_servant()
method, used in the C++ programming environment of the WLE product, is not used in the Java environment. In Java, objects are created dynamically, without prior knowledge of the classes being used. In the Java environment of the WLE product, a servant factory is used to retrieve an implementation class, given the interface repository ID. This information is stored in a server descriptor file. When a method request is received, and no servant is available for the interface, the servant factory looks up the interface and creates an object of the appropriate implementation class.
This collection of the object's implementation and data compose the run-time, active instance of the CORBA object.
When your Java server application starts, the TP Framework creates the Server object specified in the XML file. Then, the TP Framework invokes the initialize()
method. If the method returns true
, the server application starts. If the method throws the com.beasys.TobjS.InitializeFailed
exception, or returns false
, the server application does not start.
When the server application shuts down, the TP Framework invokes the release method on the Server object.
Any command-line options specified in the CLOPT
parameter for your specific server application in the SERVERS
section of the WLE domain's UBBCONFIG
file are passed to the public boolean initialize(string[] args)
method as args
. For more information about passing arguments to the server application, see Administration Guide in the WebLogic Enterprise online documentation.
Within the initialize()
method, you can include code that does the following, if applicable:
CORBA::Boolean Server::initialize(int argc, char* argv[])
{
// Create the Factory Object Reference
static_var_factory_reference =
TP::create_object_reference(
_tc_SimpleFactory->id(),
"simple_factory",
CORBA::NVList::_nil()
);
// Register the factory reference with the FactoryFinder
TP::register_factory(
static_var_factory_reference.in(),
_tc_SimpleFactory->id()
);
return CORBA_TRUE;
}
// Method to shutdown the server
void Server::release()
{
// Unregister the factory.
try {
TP::unregister_factory(
static_var_factory_reference.in(),
_tc_SimpleFactory->id()
);
}
catch (...) {
TP::userlog("Couldn't unregister the SimpleFactory");
}
}
// Method to create servants
Tobj_Servant Server::create_servant(const char*
interface_repository_id)
{
if (!strcmp(interface_repository_id,
_tc_SimpleFactory->id())) {
return new SimpleFactory_i();
}
if (!strcmp(interface_repository_id,
_tc_Simple->id())) {
return new Simple_i();
}
return 0;
}
Listing 4-6 includes the Java code from the Simpapp sample application for the Server object.
Listing 4-6
Java Server Object
import com.beasys.Tobj.TP; public class ServerImpl /**Method to start up the server*/ // Register the factory reference with the FactoryFinder return true; } catch (Exception e){ As part of server development, you determine what events cause an object to be activated and deactivated by assigning object activation policies, as follows:
extends com.beasys.Tobj.Server
{
static org.omg.CORBA.Object factory_reference;
public boolean initialize(String[] args)
{
try {
// Create the factory object reference.
factory_reference = TP.create_object_reference(
SimpleFactoryHelper.id(),
"simple_factory",
null
);
TP.register_factory(
factory_reference,
SimpleFactoryHelper.id()
);
TP.userlog("Couldn't initialize server: " +
e.getMessage());
e.printStackTrace();
return false;
}
}
/** Method to shutdown the server*/
public void release()
{
try {
TP.unregister_factory(
factory_reference,
SimpleFactoryHelper.id()
);
} catch (Exception e){
TP.userlog("Couldn't unregister the
SimpleFactory: " + e.getMessage());
e.printStackTrace();
}
}
} Defining an Object's Activation Policies
Note: You also define transaction policies in the ICF and Server Description Files. For information about using transactions in your WLE CORBA application, see Using Transactions in the WebLogic Enterprise online documentation.
The WLE software supports the following activation policies:
Activation Policy |
Description |
---|---|
The Simple interface in the Simpapp sample application is assigned the default activation policy of method. For more information about managing object state and defining object activation policies, see Creating CORBA C++ Server Applications and Creating CORBA Java Server Applications in the WebLogic Enterprise online documentation.
If your server application manages a factory that you want client applications to be able to locate easily, you need to write the code that registers that factory with the FactoryFinder object.
To write the code that registers a factory managed by your server application, you do the following:
Creating and Registering a Factory
You include an invocation to the create_object_reference() method, specifying the Interface Repository ID of the factory's OMG IDL interface or the object ID (OID) in string format. In addition, you can specify routing criteria.
Use the register_factory() method to register the factory with the FactoryFinder object in the WLE domain. The register_factory() method requires the object reference for the factory and a string identifier.
Listing 4-7 includes the code from the C++ Simpapp sample application that creates and registers a factory.
Listing 4-7 C++ Example of Creating and Registering a Factory
...
CORBA::Object_var v_reg_oref =
TP:create_object_reference(
_tc.SimpleFactory->id(), //Factory Interface ID
"simplefactory", //Object ID
CORBA::NVList::_nil() //Routing Criteria
);
TP::register_factory(
CORBA::Object_var v_reg_oref.in(),
_tc_SimpleFactory->id(),
);
...
In Listing 4-7, notice the following:
Listing 4-8 includes the code from the Java Simpapp sample application that creates and registers a factory.
Listing 4-8
Java Example of Creating and Registering a Factory
... // Save the Simple factory name. You need to include code in your server application to perform a graceful shutdown of the server application. The release()
method is provided for that purpose. Within the release()
method, you may perform any application-specific cleanup tasks that are specific to the server application, such as:
SimpleFName = new String(args[0]);
org.omg.CORBA.Object simple_oref =
TP.create_object_reference(
SimpApp.SimpleHelper.id(), // Repository ID
SimpleFName, // Object ID
null // Routing Criteria
);
// Register the factory reference with the factory finder.
TP.register_factory(
fact_oref, // factory object referenc
SimpleFName // factory name
);
... Releasing the Server Application
Once a server application receives a request to shut down, the server application can no longer receive requests from other remote objects. This has implications on the order in which server applications should be shut down, which is an administrative task. For example, do not shut down one server process if a second server process contains an invocation in its release()
method to the first server process.
During server shutdown, you may want to unregister each of the server application's factories. The invocation of the unregister_factory()
method should be one of the first actions in the release()
implementation. The unregister_factory()
method unregisters the server application's factories. This operation requires the following input arguments:
Listing 4-9 includes C++ code that releases a server application and unregistered the factories in the server application.
Listing 4-9
C++ Example of Releasing a WLE Server Application
... ... Listing 4-10 includes Java code that releases a server application and unregistered the factories in the server application.
Listing 4-10
Java Example of Releasing a WLE Server Application
... //Unregister the factory. try{ The WLE software supports the following types of client applications:
public void release()
{
TP.unregister_factory(
factory_reference,
SimpleFactoryHelper.id
);
}
/**
* Method to shutdown the server.
*/
public void release)()
{
//This method will only be called if Server.initialize()
//succeeded, therefore, we know that the factory has been
//registered with the factory finder.
//Use a try block since cleanup code should not throw
//exceptions.
TP.unregister_factory(
fact_ref, //factory object reference
SimpleFactoryHelper.id() //factory repository id
);
}catch (Exception e){
//Some exception occurred. The call to TP.userlog()
//will put the message in the ULOG file.
TP.userlog("Couldn't unregister the SimpleFactory:"
+e.getMessage());
e.printStackTrace();
}
}
...Step 4: Write the client application.
The steps for creating client applications are as follows:
Note: For information about creating an ActiveX client application, see WLE ActiveX Client Developer's Guide
in the WebLogic Enterprise online documentation.The client development steps are illustrated in Listing 4-11 and Listing 4-12, which include code from the Simpapp sample application. In the Simpapp sample application, the client application uses a factory to get an object reference to the Simple object and then invokes the to_upper() and to_lower() methods on the Simple object.
Listing 4-11 C++ Client Application from the Simpapp Sample Application
int main(int argc, char* argv[])
{
try {
// Initialize the ORB
CORBA::ORB_var var_orb = CORBA::ORB_init(argc, argv, "");
// Create the Bootstrap object
Tobj_Bootstrap bootstrap(var_orb.in(), "");
// Use the Bootstrap object to find the FactoryFinder
CORBA::Object_var var_factory_finder_oref =
bootstrap.resolve_initial_references("FactoryFinder");
// Narrow the FactoryFinder
Tobj::FactoryFinder_var var_factory_finder_reference =
Tobj::FactoryFinder::_narrow
(var_factory_finder_oref.in());
// Use the factory finder to find the Simple factory
CORBA::Object_var var_simple_factory_oref =
var_factory_finder_reference->find_one_factory_by_id(
_tc_SimpleFactory->id()
);
// Narrow the Simple factory
SimpleFactory_var var_simple_factory_reference =
SimpleFactory::_narrow(
var_simple_factory_reference.in());
// Find the Simple object
Simple_var var_simple =
var_simple_factory_reference->find_simple();
// Get a string from the user
cout << "String?";
char mixed[256];
cin >> mixed;
// Convert the string to upper case :
CORBA::String_var var_upper = CORBA::string_dup(mixed);
var_simple->to_upper(var_upper.inout());
cout << var_upper.in() << endl;
// Convert the string to lower case
CORBA::String_var var_lower = var_simple->to_lower(mixed);
cout << var_lower.in() << endl;
return 0;
}
}
Listing 4-12 Java Client Application from the Simpapp Sample Application
public class SimpleClient
{
public static void main(String args[])
// Initialize the ORB.
ORB orb = ORB.init(args, null);
// Create the Bootstrap object
Tobj_Bootstrap bootstrap = new Tobj_Bootstrap(orb, "");
// Use the Bootstrap object to locate the FactoryFinder
org.omg.CORBA.Object factory_finder_reference =
bootstrap.resolve_initial_references("FactoryFinder");
// Narrow the FactoryFinder
FactoryFinder factory_finder_reference =
FactoryFinderHelper.narrow(factory_finder_reference);
// Use the FactoryFinder to find the Simple factory.
org.omg.CORBA.Object simple_factory_reference =
factory_finder_reference.find_one_factory_by_id
(SimpleFactoryHelper.id());
// Narrow the Simple factory
SimpleFactory simple_factory_reference =
SimpleFactoryHelper.narrow(simple_factory_reference);
// Find the Simple object.
Simple simple = simple_factory_reference.find_simple();
// Get a string from the user.
System.out.println("String?");
String mixed = in.readLine();
// Convert the string to upper case.
org.omg.CORBA.StringHolder buf = new
org.omg.CORBA.StringHolder(mixed);
simple.to_upper(buf);
System.out.println(buf.value);
// Convert the string to lower case.
String lower = simple.to_lower(mixed);
System.out.println(lower);
}
}
When using transactions in a WLE CORBA application, you need to create a server process for the resource manager that interacts with a database on behalf of the WLE CORBA application. The resource manager you use must conform to the X/OPEN XA specification and you need the following information about the resource manager:
When integrating a new XA resource manager into the WLE system, the file $TUXDIR/udataobj/RM
must be updated to include information about the XA resource manager. The information is used to include the correct libraries for the XA resource manager and to automatically and properly set up the interface between the transaction manager and the XA resource manager. The format of this file is as follows:
rm_name
:
rm_structure_name
:
library_names
where rm_name
is the name of the XA resource manager, rm_structure_name
is the name of the xa_switch_t
structure that defines the name of the XA resource manager, and library_names
is the list of the object files for the XA resource manager. White space (tabs and/or spaces) is allowed before and after each of the values and may be embedded within the library_names
. The colon (:) character may not be embedded within any of the values. Lines beginning with a pound sign (#) are treated as comments and are ignored.
Use the buildtms
command to build a server process for the XA resource manager. The files that result from the buildtms
command need to be installed in the $TUXDIR/bin
directory.
For more information about the buildtms
command, see WLE Reference in the WebLogic Enterprise online documentation.
Because the WLE software offers great flexibility and many options to application designers and programmers, no two applications are alike. An application, for example, may be small and simple (a single client and server running on one machine) or complex enough to handle transactions among thousands of client and server applications. For this reason, for every WLE CORBA application being managed, the system administrator must provide a configuration file that defines and manages the components (for example, domains, server applications, client applications, and interfaces) of that application.
When system administrators create a configuration file, they are describing the WLE application using a set of parameters that the WLE software interprets to create a runnable version of the application. During the setup phase of administration, the system administrator's job is to create a configuration file. The configuration file contains the sections listed in Table 4-5.
Step 6: Create a configuration file.
Table 4-5 Sections in the Configuration File for WLE CORBA Applications
Listing 4-13 shows the configuration file for the Simpapp sample application.
Listing 4-13
Configuration File for Simpapp Sample Application
*RESOURCES *MACHINES *GROUPS *SERVERS *SERVICES When creating Java server applications, include the JavaServer
parameter in the UBBCONFIG
file to start the Java server application. For example:
*SERVERS If you are using an XA resource manager, use the JavaServerXA
parameter in place of the JavaServer
parameter to associate the XA resource manager with a specified server group. You need to include the information to open and close the resource manager in the OPENINFO
and CLOSEINFO
parameters in the GROUPS
section of the UBBCONFIG
file. The information needed to open and close the resource manager should be provided by the manufacturer of the resource manager.
There are two forms of the configuration file:
IPCKEY 55432
DOMAINID simpapp
MASTER SITE1
MODEL SHM
LDBAL N
"PCWIZ"
LMID = SITE1
APPDIR = "C:\WLEDIR\MY_SIM~1"
TUXCONFIG = "C:\WLEDIR\MY_SIM~1\results\tuxconfig"
TUXDIR = "C:\WLEDIR"
MAXWSCLIENTS = 10
SYS_GRP
LMID = SITE1
GRPNO = 1
APP_GRP
LMID = SITE1
GRPNO = 2
DEFAULT:
RESTART = Y
MAXGEN = 5
TMSYSEVT
SRVGRP = SYS_GRP
SRVID = 1
TMFFNAME
SRVGRP = SYS_GRP
SRVID = 2
CLOPT = "-A -- -N -M"
TMFFNAME
SRVGRP = SYS_GRP
SRVID = 3
CLOPT = "-A -- -N"
TMFFNAME
SRVGRP = SYS_GRP
SRVID = 4
CLOPT = "-A -- -F"
simple_server
SRVGRP = APP_GRP
SRVID = 1
RESTART = N
ISL
SRVGRP = SYS_GRP
SRVID = 5
CLOPT = "-A -- -n //PCWIZ:2468"
.
.
.
JavaServer
SRVTYPE = JAVA
MODULES = Bankapp.jar
SRVGRP = APP_GRP
SRVID = 2
SYSTEM_ACCESS = FASTPATH
CLOPT = "-A -- -M 10 TellerFactory_1"
RESTART = NStep 7: Create the TUXCONFIG file.
For more information about the tmloadcf
command, see WLE Reference in the WebLogic Enterprise online documentation.
You use the buildobjserver
command to compile and link C++ server applications. The buildobjserver
command has the following format:
buildobjserver [-o servername] [options] In the buildobjserver
command syntax:
Step 8: Compile the server application.
When creating Java server applications, use the javac
compiler to create the bytecodes for all the class files that comprise your WLE CORBA application. This set of files includes the *.java
source files generated by the m3idltojava
compiler, plus the object implementation files and server class files you created.
You use the buildjavaserver
command to build a Java ARchive (JAR) file and link the Java server applications. The buildjavaserver
command has the following format:
buildjavaserver [-s searchpath] input_file.xml In the buildjavaserver
command syntax:
You then need to specify in the APPDIR
system environment variable the location of the JAR file for your Java server application. On Windows NT systems, this directory must be on a local drive (not a networked drive). On Solaris systems, the directory can be local or remote.
The final step in the development of the CORBA client application is to produce the executable client application. To do this, you need to compile the code and then link against the client stub.
When creating CORBA C++ client applications, use the buildobjclient
command to construct a WLE client application executable. The command combines the client stubs for interfaces that use static invocation, and the associated header files, with the standard WLE libraries to form a client executable. For the syntax of the buildobjclient
command, see WLE Reference in the WebLogic Enterprise online documentation.
When creating CORBA Java client applications, see your Java ORB's documentation for information about building client executables. You need to include the wledir\udataobj\java\jdk\m3envobj.jar
file in your CLASSPATH
when you compile the CORBA Java client application. The m3envobj.jar
file contains the Java classes for the WLE environmental objects.
Use the tmboot
command to start the server processes in your WLE CORBA application. The WLE CORBA application is usually booted from the machine designated as the MASTER
in the RESOURCES
section of the UBBCONFIG
file.
For the tmboot
command to find executables, the WLE system processes must be located in $TUXDIR/bin
. Server applications should be in APPDIR,
as specified in the configuration file.
When booting server applications, the tmboot
command uses the CLOPT
, SEQUENCE
, SRVGRP
, SRVID
, and MIN
parameters from the configuration file. Server applications are booted in the order in which they appear in the configuration file.
For more information about using the tmboot
command, see WLE Reference in the WebLogic Enterprise online documentation.
Sample applications demonstrate the tasks involved in developing a WLE CORBA application, and provide sample code that can be used by client and server programmers to build their own WLE CORBA application. Code from the sample applications are used throughout the information topics in the WLE product to illustrate the development and administrative steps. For information about building and running the sample applications, see Samples in the WebLogic Enterprise online documentation.
Table 4-6 describes the additional WLE CORBA sample applications.
Step 9: Compile the client application.
Step 10: Start the WLE CORBA application.
Additional WLE CORBA Sample Applications
Table 4-6 The WLE CORBA Sample Applications
|
Copyright © 1999 BEA Systems, Inc. All rights reserved.
|