|
|
This chapter contains the following topics:
Table 3-1 outlines the development process for Java joint client/server applications.
Development Process
Table 3-1 Development Process for Java Joint Client/Server Applications
These steps are explained in detail in subsequent topics.
Because the callback object in a joint client/server application is not transactional and has no object management capabilities, you do not need to create a Server Description File (filename
.xml
) for it. However, you still need to create a Server Description File for the WLE objects in your WLE application. For information about writing a Server Description File, see Creating CORBA Java Server Applications.
You need the Java JDK version 1.2.1 to create Java joint client/server applications.
Throughout this topic, the Callback sample application is used to demonstrate the development steps. The callback object in the joint client/server application has a print_converted
method, which accepts a string from the Simple
object in the WLE server application and prints the string in uppercase and lowercase letters.
Figure 3-1 illustrates how the Callback sample application works.
The source files for the Callback sample application are located in the WLEdir\
samples\corba\callback_java
directory of the WLE software. See "Building and Running the Callback Sample Application" for more information.
You use OMG IDL to describe available CORBA interfaces to client applications. 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. For more information about OMG IDL, see Creating CORBA Client Applications.
The Callback sample application implements the CORBA interfaces listed in Table 3-2.
Software Requirements
The Callback Sample Application
Figure 3-1 How the Callback Sample Application Works
Step 1: Writing the OMG IDL
Listing 3-1 shows the simple.idl
file that defines the Callback, Simple, and SimpleFactory interfaces in the Callback sample application.
Listing 3-1
OMG IDL for the Callback Sample Application
#pragma prefix "beasys.com" interface Callback //This method prints the passed data in uppercase and lowercase interface Simple //Call the callback object in the joint client/server application interface SimpleFactory
//letters.
{
void print_converted(in string message);
};
{
void call_callback(in string val, in Callback
callback_ref);
};
{
Simple find_simple();
};
The interface specification defined in OMG IDL is used by the IDL compiler to generate skeletons and client stubs. Note that a joint client/server application uses the client stub for the WLE objects and the skeleton and client stub for the callback object.
For example, in the Callback sample application, the joint client/server application uses the skeleton and the client stub for the Callback object to implement the object. The joint client/server application also uses the client stubs for for the Simple and SimpleFactory to invoke operations on the objects. The WLE server application uses the skeletons for the Simple and SimpleFactory objects to implement the objects and the client stub for the Callback object to invoke operations on the object.
During the development process, you use the following compilers to build client stubs and skeletons.
The names of the files generated by the idltojava
and m3idltojava
commands are the same; however, the content is different. When developing a WLE application that contains a joint client/server application, it is recommended that you create two separate directories for each set of client stubs and skeletons. For the Callback sample application, the files generated by the idltojava
command are located in the client
directory and the files generated by the m3idltojava
command are located in the server
directory.
Table 3-3 lists the files that are generated by the idltojava
and the m3idltojava
commands.
Table 3-3 Files Created by the idltojava
and m3idltojava
Commands
The skeleton class that is created by the idltojava
command does not inherit from the TP Framework com.beasys.Tobj_Servant
class. Instead, the skeleton class inherits directly from the org.omg.CORBA.DynamicImplementation
class. Inheriting from com.beasys.Tobj_Servant
means the joint client/server application must explicitly create a servant for the callback object and initialize the servant's state. The servant for the callback object cannot use the activate_object
and deactivate_object
methods as they are members of the com.beasys.Tobj_Servant
class.
After you compile the OMG IDL, you need to write methods that implement the operations of each object. In a joint client/server application, you write the implementation file for the callback object. You write the implementation file for a callback object as you would write the implementation file for any other CORBA object. You also write the implementation file for the WLE object in your WLE application.
An implementation file consists of the following:
Step 3: Writing the Methods That Implement Each Interface's Operations
Listing 3-2 includes the implementation file for the Callback object.
Listing 3-2
Implementation File for the Callback Object
//The implementation file for the Callback object. The Callback Listing 3-3 includes the implementation file for the Simple object.
Listing 3-3
Implementation File for the Simple Object
import com.beasys.Tobj.TP;
//object implements the print_converted method.
class CallbackImpl extends _CallbackImplBase {
//Prints a string in upper and lower case
public void print_converted(String data) {
if (data == null)
System.out.println("Null String");
else
{
//Print input data in uppercase
System.out.println(data.toUpperCase());
//Print input data in lowercase
System.out.println(data.toLowerCase());
}
}
}
//The implementation file for the Simple interface. The Simple
//interface implements the call_callback method of the Callback //object.
public class SimpleImpl extends _SimpleImplBase
{
public void call_callback(String data, Callback
callback_ref)
//Call the print_converted method on the reference to the Callback
//object
{
callback_ref.print_converted(data);
return;
}
}
Listing 3-4 includes the implementation file for the SimpleFactory object.
Listing 3-4 Implementation File for the SimpleFactory Object
import com.beasys.Tobj.TP;
//The implementation file for the SimpleFactory object. The
//SimpleFactory object provides methods to create a Simple object.
public class SimpleFactoryImpl extends _SimpleFactoryImplBase
{
//Create an object reference to a Simple object.
public Simple find_simple()
{
try {
org.omg.CORBA.Object simple_oref =
TP.create_object_reference(
SimpleHelper.id(), // Repository id
"simple_callback", // object id
null // routing criteria
);
// Send back the narrowed reference.
return SimpleHelper.narrow(simple_oref);
} catch (Exception e){
TP.userlog("Cannot create Simple: " +e.getMessage());
e.printStackTrace();
return null;
}
}
}
In previous versions of the WLE product, Java client applications used the JDK ORB without modifications. Version 4.2 of the WLE product provides a value-added implementation of the JDK ORB. The modifications to the JDK ORB include classes and methods that support callback objects. The classes and methods for the callback objects are in the wleclient.jar file located in the following directories:
UNIX
$wledir/udataobj/java/jdk
Window NT
%wledir%\udataobj\java\jdk
To use this modified JDK ORB, Java joint client/server applications must set certain properties. Listing 3-5 contains the command to initialize the JDK ORB with the correct properties. For more information about the properties used to initialize the JDK ORB, see the CORBA Java Programming Reference.
Listing 3-5 Initializing the ORB in the Callback Sample Application
properties prop = new Properties(System.getProperties());
prop.put("org.omg.CORBA.ORBclass",
"com.beasys.CORBA.iiop.ORB");
prop.put("org.omg.CORBA.ORBSingletonclass",
"com.beasys.CORBA.idl.ORBSingleton");
System.setProperties(prop);
//Initialize the ORB
ORB orb = ORB.init(args, prop);
During development of a joint client/server application, you write the client portion of the joint client/server application as you would write any WLE client application. The client application needs to include code that does the following:
The client development steps are illustrated in Listing 3-6, which includes code from the Callback sample application. In the Callback sample application, the client portion of the joint client/server application uses a factory to get an object reference to the Simple object.
Listing 3-6 The Client Portion of the Callback Sample Application
//Create a Bootstrap object
Tobj_Bootstrap bootstrap = new Tobj_Bootstrap(orb,"");
//Create the Bootstrap object. The TOBJADDR system property
//defines the host and port.
Tobj_Bootstrap bootstrap = new Tobj_Bootstrap(orb, "");
//Use the Bootstrap object to find the FactoryFinder object.
org.omg.CORBA.Object fact_finder_oref =
bootstrap.resolve_initial_references("FactoryFinder");
//Narrow the FactoryFinder object.
FactoryFinder fact_finder_oref =
FactoryFinderHelper.narrow(fact_finder_oref);
//Use the FactoryFinder object to locate a factory for the
//Simple object.
org.omg.CORBA.Object simple_fact_oref =
fact_finder_oref.find_one_factory_by_id
(SimpleFactoryHelper.id());
//Narrow the factory.
SimpleFactory simple_factory_oref =
SimpleFactoryHelper.narrow(simple_fact_oref);
//Find the Simple object.
Simple simple = simple_factory_oref.find_simple();
To allow the use of outbound IIOP in Java joint client/server applications, the JDK ORB has been extended to implement certain POA functionality. The POA functionality is implemented through the Callbacks Wrapper object.
The Callbacks Wrapper object does the following:
For a complete description of the object policies for callback objects, see Object Policies for Callback Objects.
For a complete description of the Callbacks Wrapper object, see the CORBA Java Programming Reference.
Listing 3-7 shows how the Callbacks object is used in the Callback sample application.
Listing 3-7
Using the Callbacks Wrapper Object in the Callback Sample Application
import java.io.*; To support IIOP more efficiently in Java joint client/server applications, the Bootstrap object supports a register_callback_port
method. This method registers the callback object in a joint client/server application with the listening port of an ISH, causing invocations to the callback object to be routed through the specified ISH.
In this situation, the joint client/server application is using dual-pair connection IIOP. A joint client/server application that does not perform this registration will force server applications that invoke the callback object in the joint client/server application to use asymmetric IIOP, which uses the ORB infrastructure to locate an available ISH.
Note:
The callback object must be activated before the register_callback_port
method is called.
Listing 3-8 shows how the register_callback_port
method is used in the Callback sample application.
Listing 3-8
The register_callback_port Method in the Callback Sample Application
... Once you have an object reference to a callback object, you pass the callback object reference as a parameter to a method of a WLE object. In the Callback sample application, the Simple object (the WLE object) uses an object reference to the Callback object as a parameter to the call_callback
method. Listing 3-9 illustrates this step.
Listing 3-9
Invoking the call_callback Method
... When using joint client/server applications, the object references for the callback object must contain a host and port number, as follows:
import java.util.Properties;
import org.omg.CORBA.*;
import org.omg.CORBA.portable.ObjectImpl;
import com.beasys.*;
import com.beasys.Tobj.*;
import com.beasys.BEAWrapper.Callbacks;
...
//Create the servant for the Callback object
CallbackImpl callback_ref = new CallbackImpl();
//Use the Callbacks Wrapper object to create the callback object
Callbacks callbacks = new Callbacks(orb);
//Activate the servant and allow the ORB to accept
//callback requests.
callbacks.start_persistent_userid(callback_ref,
((ObjectImpl)callback_ref)._ids() [0],
"myID");
...Step 7: Establishing a Connection to an ISH
//Register the callback port are specified in org.omg.CORBA.ORBport
bootstrap.register_callback_port(callback_ref);
...Step 8: Invoking Operations on the Callback Object
//Call the call_callback method which invokes the Callback object
simple.call_callback(mixed, callback_ref);
...Step 9: Specifying Configuration Information
The ORB is configured by setting the org.omg.CORBA.ORBPort
system property. Every time you run the joint client/server application, you must enter the following commands to set the org.omg.CORBA.ORBPort
system property:
UNIX
java -DTOBJADDR=//Host:Port Window NT
java -DTOBJADDR=//Host:Port The administrator assigns the port number for the joint client/server application from the user range of port numbers, rather than from the dynamic range. Assigning port numbers from the user range prevents joint client/server applications from using conflicting ports.
For Java joint client/server applications, the administrator needs to boot the IIOP Server Listener (ISL) with startup parameters that enable outbound IIOP to invoke callback objects not connected to an IIOP Server Handler (ISH). The -O
option of the ISL command enables outbound IIOP. The ISL parameter is defined in the configuration file. Additional parameters allow administrators to obtain the optimum configuration for their WLE application. For more information about the ISL command, see the Reference.
Note:
The Callback sample application does not demonstrate using asymmetric IIOP. Therefore, the -O
option is not used in the configuration file.
When creating joint client/server applications, use the javac
command provided with the JDK 1.2.1 to construct an executable for the joint client/server application. The command compiles the java source code of the joint client/server application.
When compiling joint client/server applications, you need to include the following Java ARchive (JAR) files in your CLASSPATH
:
-Dorg.omg.CORBA.ORBport=
portnumber
-classpath=$CLASSPATH
JointClientServerApplication
-Dorg.omg.CORBA.ORBport=
portnumber
-classpath=%CLASSPATH%
JointClientServerApplication
Step 10: Compiling Java Joint Client/Server Applications
Note: The m3envobj.jar file is in this directory: wledir\udataobj\java\jdk .
For the syntax of the javac
command, see the CORBA Java Programming Reference.
You use the buildjavaserver
command to build the WLE server application that invokes the callback object. For information about compiling WLE server applications, see Getting Started and Creating CORBA Java Server Applications.
Note:
The Callback sample application does not use multiple threads.
Since Java as an execution environment is multithreaded, there is no need to implement the ORB org.omg.CORBA.orb.work_pending
and org.omg.CORBA.orb.perform_work
methods. These methods throw a NO_IMPLEMENT
exception when a user tries to invoke them. In addition, the org.omg.CORBA.orb.run
method does not need to be called. Be aware that any code that executes concurrently must be written to be thread-safe.
When using multiple threads in Java, the client functionality of the joint client/server application starts up in the main thread. The joint client/server application then activates the callback object using one of the start methods of the Callbacks Wrapper object. The Callbacks Wrapper object registers the servant for the callback object, and its associated object ID, in the ORB's object manager. The joint client/server application is then free to pass the object reference for the callback object to any application that may need to invoke the callback object.
Note:
The BEA version of the JDK ORB requires an explicit call to one of the start methods of the Callbacks Wrapper object to initialize the servant for the callback object and create a valid object ID. This requirement differs from the base JDK ORB, which allows implicit creation of object references through the orb.connect
method when marshaling an object reference when an application has not already done so.
Invocations on the callback object are handled by the ORB. As each request is received, the ORB validates the request against the object manager and spawns a thread for that request. Multiple requests can be made simultaneously to the same callback object, since the ORB creates a new thread for each request.
As each request terminates, the thread that runs the servant for the callback object terminates. The main thread that controls the client functionality of the joint client/server application can make as many client invocations as it needs. There is no restriction to prevent other servants defined in the joint client/server application to act as client applications and invoke on WLE objects. A call to stop_all_objects()
merely takes the callback object out of the object manager's list, thus preventing any further invocations on the callback object. Any invocation to a stopped callback object fails as if it never existed.
If the client functionality of a joint client/server application needs to retrieve the results of a callback from another thread, the client functionality must use normal thread synchronization techniques.
If any thread in the joint client/server application invokes an exit
method, all activity is stopped and the Java execution environment terminates. It is recommended to only call return()
to terminate a thread.
Perform the following steps to build and run the Callback sample application:
Threading Considerations for Java Joint Client/Server Applications
Building and Running the Callback Sample Application
The following sections describe these steps.
You need to copy the files for the Callback sample application into a work directory on your local machine. The files for the Callback sample application are located in the following directories:
Windows NT
drive:\WLEdir \samples\corba\callback_java
UNIX
/usr/local/WLEdir /samples/corba/callback_java
You will use the files listed in Table 3-4 to build and run the Callback sample application.
Note:
When running the Callback sample application on the UNIX operating system, you need to make sure the makefile
is in the path of your machine.
During the installation of the WLE software, the sample application files are marked read-only. Before you can edit or build the files in the Callback sample application, you need to change the protection attribute of the files you copied into your work directory, as follows:
Windows NT
prompt>attrib -r
drive:
\workdirectory
\*.*
UNIX
prompt>/bin/ksh
ksh prompt>chmod u+w /
workdirectory
/*.*
On the UNIX operating system platform, you also need to change the permission of runme.ksh
to give execute permission to the file, as follows:
ksh prompt>chmod +x runme.ksh
Before building and running the Callback sample application, you need to ensure that certain environment variables are set on your system. In most cases, these environment variables are set as part of the installation procedure. However, you need to check the environment variables to ensure they reflect correct information.
Table 3-5 lists the environment variables required to run the Callback sample application.
Changing the Protection Attribute on the Files for the Callback Sample Application
Verifying the Settings of the Environment Variables
To verify that the information for the environment variables defined during installation is correct, perform the following steps:
Windows NT
The Control Panel appears.
The System Properties window appears.
The Environment page appears.
UNIX
ksh prompt>printenv TUXDIR
ksh prompt>printenv JAVA_HOME
To change the settings, perform the following steps:
Windows NT
UNIX
ksh prompt>export TUXDIR= directorypath
ksh prompt>export JAVA_HOME= directorypath
Table 3-6 lists additional environment variables that may be set prior to running the Callback sample application.
Environment Variable |
Description |
---|---|
The runme
command automates the following steps:
Executing the runme Command
Note: You can also run the Callback sample application manually. The steps for manually running the Callback sample application are described in the Readme.txt file.
To build and run the Callback sample application, enter the runme command, as follows:
Windows NT
prompt>cd workdirectory
prompt>runme
UNIX
ksh prompt>cd workdirectory
ksh prompt>./runme.ksh
The Callback sample application runs and prints the following messages:
Testing simpapp
cleaned up
prepared
built
loaded ubb
booted
ran
shutdown
saved results
PASSED
Note: After executing the runme command, you may get a message indicating that the Host, Port , and IPCKEY parameters in the UBBCONFIG file conflict with an existing UBBCONFIG file. If this occurs, you need to set these parameters to different values to get the Callback sample application running on your machine.
The runme command starts the following application processes:
The BEA TUXEDO system event broker.
The following three TMFFNAME server processes are started:
The server application server process that implements the SimpleFactory and Simple interfaces. The JavaServer process has one option, simple.jar , which is the Java ARchive (JAR) file that was created for the application.
The IIOP Listener server process.
Table 3-7 lists the files in the work directory generated by the runme
command.
Table 3-8 lists files in the results
directory generated by the runme
command.
This section describes how to use the Callback sample application after the runme
command is executed.
Run the joint client/server application in the Callback sample application, as follows:
Windows NT
prompt>tmboot -y UNIX
ksh prompt>tmboot Before using another sample application, enter the following commands to stop the Callback sample application and to remove unnecessary files from the work directory:
Windows NT
prompt>tmshutdown -y
prompt>nmake -f makefile.nt clean
UNIX
ksh prompt>tmshutdown -y
ksh prompt>make -f makefile.mk clean
Using the Callback Sample Application
prompt>java -classpath %CLIENTCLASSPATH% -DTOBJADDR=%TOBJADDR
-Dorg.omg.CORBA.ORBPort=%CALLBACK_PORT% SimpleJCS
String?
Hello World
HELLO WORLD
hello world
ksh prompt>java -classpath $CLIENTCLASSPATH -DTOBJADDR=$TOBJADDR
-Dorg.omg.CORBA.ORBPort=$CALLBACK_PORT SimpleJCS
String?
Hello World
HELLO WORLD
hello world
|
Copyright © 1999 BEA Systems, Inc. All rights reserved.
|