Oracle9i CORBA Developer's Guide and Reference Release 1 (9.0.1) Part Number A90187-01 |
|
This chapter discusses advanced CORBA programming techniques, such as calling back to the client from the server. Advanced programming for security and transactions are covered in their own chapters. This chapter covers the following topics:
You can often simplify the implementation of a CORBA server object by using Oracle9i SQLJ to perform static SQL operations. Using SQLJ statements results in less code than the equivalent JDBC calls and makes the implementation easier to understand and debug. This section describes a version of the example first shown in "A First CORBA Application", but uses SQLJ rather than JDBC for the database access. Refer to the Oracle9i SQLJ Developer's Guide and Reference for complete information about SQLJ.
The only code that changes for this SQLJ implementation is in the EmployeeImpl.java
file, which implements the Employee
object. The SQLJ implementation, which can be called EmployeeImpl.sqlj
, is listed below. You can contrast that with the JDBC implementation of the same object in "Writing the Server Object Implementation".
package employeeServer; import employee.*; import java.sql.*; public class EmployeeImpl extends _EmployeeImplBase { public EmployeeInfo getEmployee (int ID) throws SQLError { try { String name = null; double salary = 0.0; #sql { select ename, sal into :name, :salary from emp where empno = :ID }; return new EmployeeInfo (name, empno, (float)salary); } catch (SQLException e) { throw new SQLError (e.getMessage ()); } } }
The SQLJ version of this implementation is considerably shorter than the JDBC version. In general, Oracle recommends that you use SQLJ where you have static SQL commands to process, and use JDBC, or a combination of JDBC and SQLJ, in applications where dynamic SQL statements are required.
To compile the EmployeeImpl.sqlj
file, issue the following SQLJ command:
% sqlj -J-classpath .:$(ORACLE_HOME)/lib/aurora_client.jar:$(ORACLE_HOME)/jdbc/lib/classes111.zip: $(ORACLE_HOME)/sqlj/lib/translator.zip:$(ORACLE_HOME)/lib/vbjorb.jar: $(ORACLE_HOME)/lib/vbjapp.jar:$(JDK_HOME)/lib/classes.zip -ser2class employeeServer/EmployeeImpl.sqlj
This command does the following:
.java
source to get a .class
file
ser2class
option translates SER files to .class
files
The SQLJ translation generates two additional class files:
employeeServer/EmployeeImpl_SJProfile0 employeeServer/EmployeeImpl_SJProfileKeys
which you must also load into the database when you execute the loadjava
command.
This example is available in complete form in the examples/corba/basic
example directory, complete with a Makefile or Windows NT batch file so that you can see how the example is compiled and loaded.
This section describes how a CORBA server object can call back to a client. The basic technique that is shown in this example is the following:
The IDL for this example is shown below. There are two separate IDL files: client.idl
and server.idl
:
/* client.idl */ module client { interface Client { wstring helloBack (); }; }; /* server.idl */ #include <client.idl> module server { interface Server { wstring hello (in client::Client object); }; };
Note that the server interface includes the interface defined in client.idl
.
The client code for this example must instantiate the client-side callback object and register it with the BOA so that it can be accessed by the server. The code performs the following steps to do this:
init()
method, with no parameters, on the ORB pseudo-object. This returns a reference to the existing client-side ORB.
The code to perform these steps is as follows:
com.visigenic.vbroker.orb.ORB orb = oracle.aurora.jndi.orb_dep.Orb.init(); org.omg.CORBA.BOA boa = orb.BOA_init (); ClientImpl client = new ClientImpl (); boa.obj_is_ready (client);
Finally, the client code calls the server object, passes it a reference to the registered client-side callback object, and prints its return value, as follows:
System.out.println (server.hello (client));
The implementation of the server-side object is simple. It receives the client-side callback object and invokes a method from this object. In this example, the server invokes the client-side helloBack
method.
package serverServer; import server.*; import client.*; import oracle.aurora.AuroraServices.ActivatableObject; public class ServerImpl extends _ServerImplBase implements ActivatableObject { public String hello (Client client) { return "I Called back and got: " + client.helloBack (); } public org.omg.CORBA.Object _initializeAuroraObject () { return this; } }
The server simply returns a string that includes the string return value from the callback.
The client-side callback server implements the desired callback method. The following example implements the helloBack
method:
package clientServer; import client.*; import oracle.aurora.AuroraServices.ActivatableObject; public class ClientImpl extends _ClientImplBase implements ActivatableObject { public String helloBack () { return "Hello Client World!"; } public org.omg.CORBA.Object _initializeAuroraObject () { return this; } }
The client-side object is just like any other server object. But in this callback example it is running in the client ORB, which can be running on a client system, not necessarily running inside an Oracle9i database server.
The Interface Repository (IFR) specified by OMG defines how to store and retrieve interface definitions. The information contained within the interface can be used internally by the ORB to retrieve information about an object reference, for type-checking the request signatures, or used externally by DII/DSI applications for instantiating objects dynamically through DII/DSI.
You store the IDL interface definition within the IFR through the Oracle9i publish
command. The publish
command stores the interface within the IFR Repository, which has been implemented using database tables.
Once stored, you can retrieve the interface definition either implicitly through the _get_interface_def
method or explicitly looking up the IFR Repository
object and invoking the standard methods to traverse through the repository.
The following sections explain how to publish and retrieve IDL interface information:
You store the IDL interface definition within the IFR through the Oracle9i JVM publish
command. This command contains the following two options for storing the IDL interface definition within the IFR:
The following publish command loads the Bank.idl
interfaces into the IFR. This is executed under the SCOTT
schema security permissions. If it already exists, the -replaceIDL
option specifies that the interfaces should be replaced with this version of Bank.idl
, which is located in /private
/idl_int
on the server node.
publish -republish -user SCOTT -password TIGER -schema SCOTT \
-service sess_iiop://dlsun164:2481:orcl \ /test/myBank bankServer.AccountManagerImpl \ Bank.AccountManagerHelper -idl /private/idl_int/Bank.idl -replaceIDL
The interfaces within the IDL are loaded within the schema that executes the publish
command. Thus, if another user loads an IDL of the same name, it will not overwrite this one because they exist within separate schemas.
The interfaces are removed from the IFR when you remove the associated PublishedObject. To remove the published object and the interfaces added with the above myBank
example, do the following:
sess_sh -command "remove /test/myBank -user SCOTT -password TIGER \-service sess_iiop://dlsun164:2481:orcl" -idl
The current implementation of the IFR does not allow circular references between interfaces within a module. That is, you cannot have two interfaces which reference each other. The following example shows an invalid module definition, where x
references y
and y
references x
:
module circular { interface x; interface y { x func1(); }; interface x { y func2(); }; };
The IFR is implemented using SQL tables. Thus, you must have the correct permissions to change or remove an existing IDL from the IFR. The user who created the IDL automatically has permission. Otherwise, this user must grant permission for any other user to modify or remove the IDL from within the IFR. Any grant executed on a PublishedObject also extends to the interface that was stored in the IFR with the -idl
option on the publish
command.
See the security chapter in the Oracle9i Java Developer's Guide for information on granting permissions.
You can retrieve the interface definition implicitly through the org.omg.CORBA.Object._get_interface_def
method. The object returned should be cast to InterfaceDef
. The following code retrieves the InterfaceDef
object for the Bank.Account
:
AccountManager manager = (AccountManager)ic.lookup (serviceURL + objectName); Bank.Account account = manager.open(name); org.omg.CORBA.InterfaceDef intf = (org.omg.CORBA.InterfaceDef) account._get_interface_def();
Once retrieved, you can execute any of the InterfaceDef
methods for retrieving information about the interface.
All defined interfaces stored in the IFR are stored in a hierarchy. The top level of the hierarchy is a Repository
object, which is also a Container
object. All objects under the Repository
object are Contained
objects. You can parse down through the Container
objects, reviewing the Contained
objects, until you find the particular interface definition you want.
The Repository
object is pre-published under the name "/etc/ifr
". To retrieve a prepublished IFR Repository
object, look up the "/etc/ifr
" object as shown below:
Repository rep = (Repository)ic.lookup(serviceURL + "/etc/ifr");
Once the Repository
object is retrieved, you can traverse through the hierarchy until you reach the object you are interested in. The methods for each object type, InterfaceDef
, and others are documented fully in the OMG CORBA specification.
As shown in Figure5-1, the Account
interface is contained within AccountManager
, which is contained within the Repository
object.
Once you retrieve the IFR object, you can traverse through all stored definitions within the IFR. The print
method in Example5-1 prints out all stored definitions located within the IFR.
public void print( ) throws org.omg.CORBA.UserException { //retrieve the repository as a container... as the top level container org.omg.CORBA.Container container =
(Container)ic.lookup(serviceURL + "/etc/ifr"); //All objects in the IFR are Contained, except for the Repository. //Retrieve the contents of the Repository, which would be all objects that //it contains. org.omg.CORBA.Contained[] contained = container.contents(org.omg.CORBA.DefinitionKind.dk_all, true); //The length is equal to the number of objects contained within the IFR for(int i = 0; i < contained.length; i++) { { //Each Contained object has a description. org.omg.CORBA.ContainedPackage.Description description =
contained[i].describe(); //Each object is of a certain type, which is retrieved by the value method. switch(contained[i].def_kind().value()) { case org.omg.CORBA.DefinitionKind._dk_Attribute: printAttribute(org.omg.CORBA.AttributeDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Constant: printConstant(org.omg.CORBA.ConstantDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Exception: printException(org.omg.CORBA.ExceptionDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Interface: printInterface(org.omg.CORBA.InterfaceDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Module: printModule(org.omg.CORBA.ModuleDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Operation: printOperation(org.omg.CORBA.OperationDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Alias: printAlias(org.omg.CORBA.AliasDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Struct: printStruct(org.omg.CORBA.StructDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Union: printUnion(org.omg.CORBA.UnionDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_Enum: printEnum(org.omg.CORBA.EnumDefHelper.narrow(contained[i])); break; case org.omg.CORBA.DefinitionKind._dk_none: case org.omg.CORBA.DefinitionKind._dk_all: case org.omg.CORBA.DefinitionKind._dk_Typedef: case org.omg.CORBA.DefinitionKind._dk_Primitive: case org.omg.CORBA.DefinitionKind._dk_String: case org.omg.CORBA.DefinitionKind._dk_Sequence: case org.omg.CORBA.DefinitionKind._dk_Array: default: break; } } }
There is only one special consideration when you use the CORBA Tie, or delegation, mechanism rather than the inheritance mechanism for server object implementations. In the Tie case, you must implement the oracle.aurora.AuroraServices.ActivatableObject
interface. This interface has a single method: _initializeAuroraObject().
Note that earlier releases of the Oracle9i ORB required you to implement this method for all server objects. For the current release, its implementation is required only for Tie objects.
The implementation of _initializeAuroraObject()
for a tie class is typically:
import oracle.aurora.AuroraServices.ActivatableObject; ... public org.omg.CORBA.Object _initializeAuroraObject () { return new _tie_Hello (this); ...
where _tie_<interface_name>
is the tie class generated by the IDL compiler.
Additionally, you must always include a public, parameterless constructor for the implementation object.
See the "TIE Example" for a complete example that shows how to use the Tie mechanism.
Oracle9i updated its ORB implementation to Visibroker 3.4, which is compatible with both JDK 1.1 and Java 2.
JDK 1.1 did not contain an OMG CORBA implementation. Thus, when you imported the Inprise libraries and invoked the CORBA methods, it always invoked the Visibroker implementation. The Sun Microsystems Java 2 contains an OMG CORBA implementation. Thus, if you invoke the CORBA methods without any modifications--as discussed below--you will invoke the Sun Microsystems CORBA implementation, which can cause unexpected results. To avoid this, you should bypass the Sun Microsystems CORBA implementation.
Here are the three methods for initializing the ORB on the client-side and recommendations for bypassing the Sun Microsystems CORBA implementation:
If you are using JNDI on the client to access CORBA objects that reside in the server, no code changes are necessary. However, you must regenerate your CORBA stubs and skeletons.
If your client environment uses JDK 1.1, you do not need to change your existing code. However, you must regenerate your stubs and skeletons.
If your client environment has been upgraded to Java 2, you can initialize the ORB through the oracle.aurora.jndi.orb_dep.Orb.init
method. This method guarantees that when you initialize the ORB, it will initialize only a single ORB instance. That is, if you use the Java 2 ORB interface, it returns a new ORB instance each time you invoke the init
method. The Oracle9i init
method initializes a singleton ORB instance. Each successive call to init
returns an object reference to the existing ORB instance.
In addition, the Oracle9i ORB interface manages the session-based IIOP connection.
There are several init
methods, each with a different parameter list. The following describes the syntax and parameters for each init
method.
If you execute the ORB.init
method that takes no parameters, it does the following:
public com.visigenic.vbroker.orb.ORB init();
If you execute the ORB.init
method that takes the ORB properties as the only parameter, it does the following:
public org.omg.CORBA.ORB init(Properties props);
If you execute the ORB.init
method that takes the ORB properties and ORB command-line arguments, it always creates an ORB instance and returns the reference to you.
public org.omg.CORBA.ORB init(String[] args, Properties props);
Parameter | Description |
---|---|
Properties props |
ORB system properties |
String[] args |
Arguments that are passed to the ORB instance |
The following example shows a client instantiating an ORB using the Oracle9i Orb
class.
// Create the client object and publish it to the orb in the client
// Substitute Oracle9i's Orb.init for OMG ORB.init call
// old way: org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init ();
com.visigenic.vbroker.orb.ORB orb = oracle.aurora.jndi.orb_dep.Orb.init();
If you execute the ORB.init
method that provides the ORB properties, username, password, and role as parameters, it does the following:
Use this method when your client chooses not to use JNDI for ORB initialization and it receives a reference to an existing object from another client. To access an active object within a session, the new client must authenticate itself to the database in one of two ways:
init
method parameters. Then, when you invoke a method on the supplied object reference, the username, password, and role are passed implicitly on the first message to authenticate the client to the database.
authenticate
method of the login object. Then, it executes any method on the object.
This method is how a second client invokes an active object in an established session.
public org.omg.CORBA.ORB init(String un, String pw, String role, boolean ssl, java.util.Properties props);
If you have implemented a pure CORBA client--that is, you do not use JNDI--you must set the following properties before the ORB initialization call. These properties direct the call to the Oracle9i implementation rather than the Java 2 implementation. This ensures the behavior that you expect. The behavior expected from Visibroker is as follows:
ORB.init
more than once, Oracle9i creates only a single ORB instance. If you do not set these properties, be aware that each invocation of ORB.init
will create a new ORB instance.
Property | Assign Value |
---|---|
org.omg.corba.ORBClass |
com.visigenic.vbroker.orb |
org.omg.corba.ORBSingletonClass |
com.visigenic.vbroker.orb |
The following example shows how to set up the OMG properties for directing the OMG CORBA init
method to the Visibroker implementation.
System.getProperties().put("org.omg.CORBA.ORBClass",
"com.visigenic.vbroker.orb.ORB"); System.getProperties().put("org.omg.CORBA.ORBSingletonClass",
"com.visigenic.vbroker.orb.ORB");
Or you can set the properties on the command line, as follows:
java -Dorg.omg.CORBA.ORBClass=com.visigenic.vbroker.orb.ORB
-Dorg.omg.CORBA.ORBSingletonClass=com.visigenic.vbroker.orb.ORB
The tools provided with Oracle9i, such as publish
, have been modified to work with either a JDK 1.1 or Java 2 environment. However, any code that has been generated or loaded with the 8.1.5 version of any tool will not succeed. Make sure that you always use the current version of all tools. This rule applies to your CORBA stubs and skeletons. In migrating any release 8.1.5 applications, you must regenerate all stubs and skeletons with the current version of the IDL compiler.
You invoke a server object from an applet in the same manner as from a client. The only differences are the following:
ORBdisableLocator
, ORBClass
, and ORBSingletonClass.
The security sandbox constricts your applet from accessing anything on the local disk or from connecting to a remote host other than the host that the applet was downloaded from. If you create a signed JAR file as a trusted party, you can bypass the sandbox security. See http://java.sun.com
for more information on applet sandbox security and signed JAR files.
You perform the JNDI lookup within the applet the same as within any Oracle Java client, except that you set the following property within the initial context:
env.put(ServiceCtx.APPLET_CLASS, this);
By default, you do not need to install any JAR files on the client to run the applet. However, if you want to place the Oracle JAR files on the client machine, set the ClassLoader
property in the InitialContext
environment, as follows:
env.put('ClassLoader', this.getClass().getClassLoader());
The following shows the init
method within an applet that invokes the Bank example. The applet sets up the initial context--including setting the APPLET_CLASS
property--and performs the JNDI lookup giving the URL.
public void init() { // This GUI uses a 2 by 2 grid of widgets. setLayout(new GridLayout(2, 2, 5, 5)); // Add the four widgets. add(new Label("Account Name")); add(_nameField = new TextField()); add(_checkBalance = new Button("Check Balance")); add(_balanceField = new TextField()); // make the balance text field non-editable. _balanceField.setEditable(false); try { // Initialize the ORB (using the Applet).Hashtable env = new Hashtable();
env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
env.put(Context.SECURITY_PRINCIPAL, "scott");
env.put(Context.SECURITY_CREDENTIALS, "tiger");
env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);
env.put(ServiceCtx.APPLET_CLASS, this);
Context ic = new InitialContext(env);
_manager = (AccountManager)ic.lookup
} catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); throw new RuntimeException(); } }
("sess_iiop://hostfunk:2222/test/myBank");
Within the action
method, the applet invokes methods off of the retrieved object. In this example, the open
method of the retrieved AccountManager
object is invoked.
public boolean action(Event ev, Object arg) {
if(ev.target == _checkBalance) {
// Request the account manager to open a named account.
// Get the account name from the name text widget.
Bank.Account account = _manager.open(_nameField.getText());
// Set the balance text widget to the account's balance.
_balanceField.setText(Float.toString(account.balance()));
return true;
}
return false;
}
Oracle9i supports only the following Java plug-ins for the HTML page that loads in the applet: JDK 1.1, Java 2, and Oracle JInitiator. Each plug-in contains different syntax for the applet information. However, each HTML page may contain definitions for the following two properties:
ORBdisableLocator
set to TRUE--Required for all applets.
ORBClass
and ORBSingletonClass
definitions--Required for the applets that use the Java 2 or JInitiator plug-in.
The examples in the following sections show how to create the correct HTML definition for each plug-in type. Each HTML definition defines the applet bank example.
<pre> <html> <title>Applet talking to 8i</title> <h1>applet talking to 8i using java plug in 1.1 </h1> <hr> The bank example Specify the plugin in codebase, the class within the CODE parameter, the JAR files in the ARCHIVE parameter, the plugin version in the type parameter, and set ORBdisableLocator to true. <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = 500 HEIGHT = 50
codebase="http://java.sun.com/products/plugin/1.1/
<COMMENT> Set the plugin version in the type, set ORBdisableLocator to true, the applet class within the java_CODE tag, the JAR files in the java_ARCHIVE tag, and the plug-in source site within the pluginspage tag.
jinstall-11-win32.cab#Version=1,1,0,0">
<PARAM NAME = CODE VALUE = OracleClientApplet.class >
<PARAM NAME = ARCHIVE VALUE = "oracleClient.jar,
aurora_client.jar,vbjorb.jar,vbjapp.jar" >
<PARAM NAME="type" VALUE="application/x-java-applet;version=1.1">
<PARAM NAME="ORBdisableLocator" VALUE="true"><EMBED type="application/x-java-applet;version=1.1"
ORBdisableLocator="true"
java_CODE = OracleClientApplet.class
java_ARCHIVE = "oracleClient.jar,
aurora_client.jar,vbjorb.jar,vbjapp.jar"
WIDTH = 500 HEIGHT = 50
pluginspage="http://java.sun.com/products/plugin/1.1/plugin-install.html">
<NOEMBED></COMMENT> </NOEMBED></EMBED> </OBJECT> </center> <hr> </pre>
<pre> <html> <title>applet talking to 8i</title> <h1>applet talking to 8i using Java plug in 1.2 </h1> <hr> The bank example Specify the plugin in codebase, the class within the CODE parameter, the JAR files in the ARCHIVE parameter, the plugin version in the type parameter, and set ORBdisableLocator to true. <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = 500 HEIGHT = 50
codebase="http://java.sun.com/products/plugin/1.2/jinstall-11-win32.cab#
<COMMENT> Set the plugin version in the type, set ORBdisableLocator to true, the ORBClass and ORBSingletonClass to the correct ORB class, the applet class within the java_CODE tag, the JAR files in the java_ARCHIVE tag, and the plug-in source site within the pluginspage tag.
Version=1,1,0,0">
<PARAM NAME = CODE VALUE = OracleClientApplet.class >
<PARAM NAME = ARCHIVE VALUE = "oracleClient.jar,
aurora_client.jar,vbjorb.jar,vbjapp.jar" >
<PARAM NAME="type" VALUE="application/x-java-applet;version=1.1.2">
<PARAM NAME="ORBdisableLocator" VALUE="true">
<PARAM NAME="org.omg.CORBA.ORBClass" VALUE="com.visigenic.vbroker.orb.ORB">
<PARAM NAME="org.omg.CORBA.ORBSingletonClass"
VALUE="com.visigenic.vbroker.orb.ORB"><EMBED type="application/x-java-applet;version=1.1.2"
ORBdisableLocator="true"
org.omg.CORBA.ORBClass="com.visigenic.vbroker.orb.ORB"
org.omg.CORBA.ORBSingletonClass="com.visigenic.vbroker.orb.ORB"
java_CODE = OracleClientApplet.class
java_ARCHIVE = "oracleClient.jar,
aurora_client.jar,vbjorb.jar,vbjapp.jar"
WIDTH = 500 HEIGHT = 50
pluginspage="http://java.sun.com/products/plugin/1.2/plugin-install.html">
<NOEMBED></COMMENT> </NOEMBED></EMBED> </OBJECT> </center> <hr> </pre>
<h1> applet talking to 8i using JInitiator 1.1.7.18</h1> <COMMENT> Set the plugin version in the type, set ORBdisableLocator to true, the ORBClass and ORBSingletonClass to the correct ORB class, the applet class within the java_CODE tag, the source of the applet in the java_CODEBASE and the JAR files in the java_ARCHIVE tag.<EMBED type="application/x-jinit-applet;version=1.1.7.18"
java_CODE="OracleClientApplet"
java_CODEBASE="http://hostfunk:8080/applets/bank"
java_ARCHIVE="oracleClient.jar,aurora_client.jar,vbjorb.jar,vbjapp.jar"
WIDTH=400
HEIGHT=100
ORBdisableLocator="true"
org.omg.CORBA.ORBClass="com.visigenic.vbroker.orb.ORB"
org.omg.CORBA.ORBSingletonClass="com.visigenic.vbroker.orb.ORB"
serverHost="orasundb"
serverPort=8080
<NOEMBED> </COMMENT> </NOEMBED> </EMBED>
You can interoperate with Oracle9i from a client that uses another vendor's ORB. To do so, the vendor must provide the functionality that Oracle9i uses by being part of the database: functions such as session-based connections, extended CosNaming, and the login protocol. To provide this functionality, your ORB vendor must work with Oracle's Product Management to provide libraries for you.
All client-side functionality has been packaged into aurora_client.jar
. This JAR file has been broken into two JAR files for interoperating with your ORB vendor:
aurora_orbindep.jar
--includes ORB-independent features, such as JNDI
aurora_orbdep.jar
--includes Oracle ORB dependent functionality, such as session-based communication, the login protocol, and security context
Your ORB vendor needs to provide you with the aurora_orbdep.jar
file. Thus, you include the vendor's aurora_orbdep.jar
file and the Oracle-provided aurora_orbindep.jar
file to replace aurora_client.jar
.
The aurora_orbdep.jar
includes the following functionality:
Function | Description |
---|---|
login |
The login protocol performs the challenge/response protocol for authenticating the client to the database. See "IIOP Security" for more information. |
bootstrap |
The boot service obtains key services, such as CosNaming. |
extended CosNaming |
The Oracle9i ORB extended CosNaming to automatically instantiate an object upon first lookup. |
Session IIOP |
Session IIOP is implemented to allow one client to connect to more than a single IIOP session at the same time. See Chapter 3, "Configuring IIOP Applications", for more information. |
Credentials |
This is the security context interceptor for the credential type of authentication. |
Perform the following if you choose to use the Oracle-provided ORB on your client:
aurora_client.jar
in a directory that exists in the CLASSPATH.
Perform the following if you choose to use another vendor's ORB on your client:
aurora_orbindep.jar
in a directory that exists in the CLASSPATH.
aurora_orbdep.jar
.
aurora_orbdep.jar
in a directory that exists in the CLASSPATH.
With C++ clients, the ORB vendor must provide the aurora_client.jar
file functionality in shared libraries. The vendor will make use of the Oracle-provided C++ login protocol for authentication. All clients are required to authenticate themselves to the database. One of the methods for authenticating is through the login protocol.
The login protocol is an Oracle-specific design, used for logging in to a database by providing a username and password to authenticate the client. The following example shows how to write a sample C++ CORBA client to Oracle9i. This example uses the Visigenics C++ ORB for its client-side ORB.
The following C++ client uses the Visigenics C++ ORB for the client-side ORB. Your implementation can be different, depending on the type of ORB you use.
#include <Login.h> #include <oracle_orbdep.h> // set up host, port, and SID char *sid = NULL; char *host = argv[1]; int port = atol(argv[2]); if(argc == 4) sid = argv[3]; // set up username, password, and role wchar_t *username = new wchar_t[6]; username[0] = 's'; username[1] = 'c'; username[2] = 'o'; username[3] = 't'; username[4] = 't'; username[5] = '\0'; wchar_t *password = new wchar_t[6]; password[0] = 't'; password[1] = 'i'; password[2] = 'g'; password[3] = 'e'; password[4] = 'r'; password[5] = '\0'; wchar_t *role = new wchar_t[1]; role[0] = '\0'; // Get the Name service Object reference AuroraServices::PublishingContext_ptr rootCtx = NULL; // Contact Visibroker's boot service for initializing rootCtx = VisiCppBootstrap::getNameService (host, port, sid); // Get the pre-published login object reference AuroraServices::PublishedObject_ptr loginPubObj = NULL; AuroraServices::LoginServer_ptr serv = NULL; CosNaming::NameComponent *nameComponent = new CosNaming::NameComponent[2]; nameComponent[0].id = (const char *)"etc"; nameComponent[0].kind = (const char *)""; nameComponent[1].id = (const char *)"login"; nameComponent[1].kind = (const char *)""; CosNaming::Name *name1 = new CosNaming::Name(2, 2, nameComponent, 0); // Lookup this object in the Name service CORBA::Object_ptr loginCorbaObj = rootCtx->resolve (*name1); // Make sure it is a published object loginPubObj = AuroraServices::PublishedObject::_narrow (loginCorbaObj); // create and activate this object (non-standard call) loginCorbaObj = loginPubObj->activate_no_helper (); serv = AuroraServices::LoginServer::_narrow (loginCorbaObj);// Create a client login proxy object and authenticate to the DB
oracle_orbdep *_visi = new oracle_orbdep(serv);
Login login(_visi);
boolean res = login.authenticate(username, password, role);
If, when using another vendor's ORB, the ORB vendor does not support session-based IIOP, you can use a regular IIOP port. Any client that uses a regular IIOP transport cannot access multiple sessions.
To configure a non-session-based IIOP listener, you must do the following:
oracle.aurora.server.GiopServer
instead of oracle.aurora.server.SGiopServer
.
mts_dispatchers="(protocol=tcp | tcps)
(presentation=oracle.aurora.server.GiopServer)"
ServiceCtx.IIOP
, as shown below:
Hashtable env = new Hashtable();
env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
env.put(Context.SECURITY_PRINCIPAL, user);
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);
env.put("TRANSPORT_TYPE", ServiceCtx.IIOP);
Context ic = new InitialContext(env);
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|