Programming WebLogic RMI
The following sections describe concepts and procedures relating to configuring WebLogic Server for RMI-IIOP:
To facilitate the use of IIOP, always specify a valid IP address or DNS name for the Listen Address attribute in the configuration file (config.xml
) to listen for connections.
The Listen Address default value of null
allows it to "listen on all configured network interfaces". However, this feature only works with the T3 protocol. If you need to configure multiple listen addresses for use with the IIOP protocol, then use the Network Channel feature, as described in "Configuring Network Resources".
The following sections provide information to consider when implementing IIOP network channel addresses for thin clients.
Many typical environments use firewalls, proxys, or other devices that hide the application server's true IP address. Because IIOP relies on a per-object addressing scheme where every object contains a host and port, anything that masks the true IP address of the server will prevent the external client from maintaining a connection. To prevent this situation, set the PublicAddress on the server IIOP network channel to the virtual IP that the client sees.
IIOP clients publish addressing information that is used by the application server to establish a connection. In some situations, such as running a VPN where clients have more than one connection, the server cannot see the IP address published by the client. In this situation, you have two options:
-Dweblogic.corba.client.bidir=true
In this instance, the server does not need the IP address published by the client because the server uses the inbound connection for outbound requests.
-Dcom.sun.CORBA.ORBServerHost=client_ipaddress
The IIOPs Thin Client Proxy provides a WebLogic thin client the ability to proxy outbound requests to a server. In this situation, each user routes all outbound requests through their proxy. The user's proxy then directs the request to the WebLogic Server. You should use this method when it is not practical to implement a Network Channel. To enable a proxy, set the following properties:
-Diiops.proxyHost=<host>
-Diiops.proxyPort=<port>
-Diiops.proxyHost=https.proxyHost
-Diiops.proxyPort=https.proxyPort
You should consider the following security implications:
CONNECT
attribute on the proxy server. These environments should use HTTPS tunneling. For more information, see Setting Up WebLogic Server for HTTP Tunneling in Configuring and Managing WebLogic Server.
The Java clients that support SSL are the thin client and the WLS-IIOP client. To use SSL with these clients, simply specify an ssl url.
WebLogic Server provides services that allow CORBA clients to access RMI remote objects. As an alternative method, you can also host a CORBA ORB (Object Request Broker) in WebLogic Server and delegate incoming and outgoing messages to allow CORBA clients to indirectly invoke any object that can be bound in the server.
Here are the main steps to create the objects that work together to delegate CORBA calls to an object hosted by WebLogic Server.
Figure 7-1 is a diagram of a CORBA client invoking an EJB by delegating the call to an implementation class that connects to the server and operates upon the EJB. Using a similar architecture, the reverse situation will also work. You can have a startup class that brings up an ORB and obtains a reference to the CORBA implementation object of interest. This class can make itself available to other WebLogic objects throughout the JNDI tree and delegate the appropriate calls to the CORBA object.
Figure 7-1 CORBA Client Invoking an EJB with a Delegated Call
The following code example creates an implementation class that connects to the server, looks up the Foo object in the JNDI tree, and calls the bar method. This object is also a startup class that is responsible for initializing the CORBA environment by:
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import java.rmi.*;
import javax.naming.*;
import weblogic.jndi.Environment;
public class FooImpl implements Foo
{
public FooImpl() throws RemoteException {
super();
}
public void bar() throws RemoteException, NamingException {
// look up and call the instance to delegate the call to...
weblogic.jndi.Environment env = new Environment();
Context ctx = env.getInitialContext();
Foo delegate = (Foo)ctx.lookup("Foo");
delegate.bar();
System.out.println("delegate Foo.bar called!");
}
public static void main(String args[]) {
try {
FooImpl foo = new FooImpl();
// Create and initialize the ORB
ORB orb = ORB.init(args, null);
// Create and register the tie with the ORB
_FooImpl_Tie fooTie = new _FooImpl_Tie();
fooTie.setTarget(foo);
orb.connect(fooTie);
// Get the naming context
org.omg.CORBA.Object o = \
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(o);
// Bind the object reference in naming
NameComponent nc = new NameComponent("Foo", "");
NameComponent path[] = {nc};
ncRef.rebind(path, fooTie);
System.out.println("FooImpl created and bound in the ORB registry.");
}
catch (Exception e) {
System.out.println("FooImpl.main: an exception occurred:");
e.printStackTrace();
}
}
}
The Common Secure Interoperability Specification, Version 2 (CSIv2) is an Open Management Group (OMG) specification that addresses the requirements of Common Object Request Broker Architecture (CORBA) security for interoperable authentication, delegation, and privileges. See Common Secure Interoperability Version 2 (CSIv2) in Understanding WebLogic Security.
Use the following steps to use CSIv2 to authenticate an inbound call from a remote domain:
Note: This feature works correctly only when the bootstrap is through a hardware load-balancer.
An optional enhancement for WebLogic Server 9.0 BEA ORB and higher, supports hardware loadbalancing by forcing reconnection when bootstrapping. This allows hardware load-balancers to balance connection attempts
In most situations, once a connection has been established, the next NameService lookup is performed using the original connection. However, since this feature forces re-negotiation of the end point to the hardware load balancer, all in-flight requests on any existing connection are lost.
Use the -Dweblogic.system.iiop.reconnectOnBootstrap
system property to set the connection behavior of the BEA ORB. Valid values are:
Environments requiring a hardware loadbalancer should set this property to true.
The following sections outline various issues relating to WebLogic RMI-IIOP.
Use WebLogic Server with JDK 1.3.1_01 or higher. Earlier versions are not RMI-IIOP compliant. Note the following about these earlier JDKs:
Many of these items are impossible to support both ways. Where there was a choice, WebLogic supports the spec-compliant option.
BEA Systems strongly recommends developing Java clients with the RMI client model if you are going to use RMI-IIOP. Developing a Java IDL client can cause naming conflicts and classpath problems, and you are required to keep the server-side and client-side classes separate. Because the RMI object and the IDL client have different type systems, the class that defines the interface for the server-side will be very different from the class that defines the interface on the client-side.
To pass objects by value, you need to use value types (see Chapter 5 of the CORBA/IIOP 2.4.2 Specification for further information) You implement value types on each platform on which they are defined or referenced. This section describes the difficulties of passing complex value types, referencing the particular case of a C++ client accessing an Entity bean on WebLogic Server.
One problem encountered by Java programmers is the use of derived datatypes that are not usually visible. For example, when accessing an EJB finder the Java programmer will see a Collection or Enumeration, but does not pay attention to the underlying implementation because the JDK run-time will classload it over the network. However, the C++, CORBA programmer must know the type that comes across the wire so that he can register a value type factory for it and the ORB can unmarshal it.
Simply running ejbc
on the defined EJB interfaces will not generate these definitions because they do not appear in the interface. For this reason ejbc
will also accept Java classes that are not remote interfaces—specifically for the purpose of generating IDL for these interfaces. Review the /iiop/ejb/entity/cppclient
example to see how to register a value type factory.
Java types that are serializable but that define writeObject()
are mapped to custom value types in IDL. You must write C++ code to unmarshal the value type manually. See example code from the iiop/ejb/entity/tuxclient/ArrayList_i.cpp
file at http://dev2dev.bea.com/.
Note: When using Tuxedo, you can specify the -i qualifier to direct the IDL compiler to create implementation files named FileName_i.h and FileName_i.cpp. For example, this syntax creates the TradeResult_i.h and TradeResult_i.cpp implementation files:
idl -IidlSources -i idlSources\examples\iiop\ejb\iiop\TradeResult.idl
The resulting source files provide implementations for application-defined operations on a value type. Implementation files are included in a CORBA client application.
Until recently insufficient standards existed for propagating client identity from a CORBA client. If you have problems with client identity from foreign ORBs, you may need to implement one of the following methods:
<anonymous>
. You can set the user and password in the config.xml
file to establish a single identity for all clients connecting over IIOP to a particular instance of WebLogic Server, as shown in the example below:<Server
Name="myserver"
NativeIOEnabled="true"
DefaultIIOPUser="Bob"
DefaultIIOPPassword="Gumby1234"
ListenPort="7001">
IIOPEnabled
attribute in the config.xml
. The default value is "true
"; set this to "false
" only if you want to disable IIOP support. No additional server configuration is required to use RMI over IIOP beyond ensuring that all remote objects are bound to the JNDI tree to be made available to clients. RMI objects are typically bound to the JNDI tree by a startup class. EJB homes are bound to the JNDI tree at the time of deployment. WebLogic Server implements a CosNaming Service
by delegating all lookup calls to the JNDI tree.corbaname
and corbaloc
JNDI references. See the CORBA/IIOP 2.4.2 Specification. One feature of these references is that you can make an EJB or other object hosted on one WebLogic Server available over IIOP to other Application Servers. So, for instance, you could add the following to your ejb-jar.xml
:<ejb-reference-description>
<ejb-ref-name>WLS</ejb-ref-name>
<jndi-name>corbaname:iiop:1.2@localhost:7001#ejb/j2ee/interop/foo</jndi-name>
</ejb-reference-description>
The reference-description stanza maps a resource reference defined in ejb-jar.xml
to the JNDI name of an actual resource available in WebLogic Server. The ejb-ref-name
specifies a resource reference name. This is the reference that the EJB provider places within the ejb-jar.xml
deployment file. The jndi-name
specifies the JNDI name of an actual resource factory available in WebLogic Server.
Note: The iiop:1.2
contained in the <jndi-name>
section. This release contains an implementation of GIOP (General-Inter-Orb-Protocol) 1.2. The GIOP specifies formats for messages that are exchanged between inter-operating ORBs. This allows interoperability with many other ORBs and application servers. The GIOP version can be controlled by the version number in a corbaname
or corbaloc
reference.
These methods are not required when using WLInitialContextFactory
in RMI clients or can be avoided by using the WebLogic C++ client. See example code from the iiop/ejb/stateless/sectuxclient
example at http://dev2dev.bea.com/.
WebLogic Tuxedo Connector provides interoperability between WebLogic Server applications and Tuxedo services.
You should consider using WebLogic Tuxedo Connector if you have developed applications on Tuxedo and are moving to WebLogic Server, or if you are seeking to integrate legacy Tuxedo systems into your newer WebLogic environment. WebLogic Tuxedo Connector allows you to leverage Tuxedo's highly scalable and reliable CORBA environment.
The connector uses an XML configuration file that allows you to configure the WebLogic Server to invoke Tuxedo services. It also enables Tuxedo to invoke WebLogic Server Enterprise Java Beans (EJBs) and other applications in response to a service request.
The following documentation provides information on the Weblogic Tuxedo Connector, as well as building CORBA applications on Tuxedo:
WebLogic Tuxedo Connector IIOP samples are provided with the WebLogic Server product. The samples are located in the SAMPLES_HOME\server\examples\src\examples\iiop\ejb
directory . A description of each sample and instructions on how to build, configure, and run a sample, are provided in the package-summary.html
file. You can modify these code examples and reuse them.
In WebLogic Server releases 8.1 and higher, the RMI-IIOP runtime has been extended to support all CORBA object types (as opposed to RMI valuetypes) and CORBA stubs. This enhancement provides the following features:
The following sections provide information on how to use the CORBA API:
This section provides information on how to implement a typical development model for customers wanting to use the CORAB API for outbound calls.
This section provides examples of several mechanisms to access the WebLogic ORB. Each of these mechanisms achieve the same effect and their constituent components can be mixed to some degree. The object returned by narrow()
will be a CORBA stub representing the external ORB service and can be invoked on as a normal CORBA reference. Each of the following code examples assumes that the CORBA interface is call MySvc and the service is hosted at "where" in a foreign ORB's CosNaming service located at exthost:extport
:
.
.
.ORB orb = (ORB)new InitialContext().lookup("java:comp/ORB");
NamingContext nc = NamingContextHelper.narrow(orb.string_to_object("corbaloc:iiop:exthost:extport/NameService"));
MySvc svc = MySvcHelper.narrow( nc.resolve(new NameComponent[] { new NameComponent("where", "")}));
.
.
.
.
.
.
ORB orb = ORB.init();
MySvc svc = MySvcHelper.narrow(orb.string_to_object("corbaname:iiop:exthost:extport#where"));
.
.
.
.
.
.
MySvc svc = MySvcHelper.narrow(new InitialContext().lookup("corbaname:iiop:exthost:extport#where"));
.
.
.
The WebLogic ORB supports most client ORB functions, including DII (Dynamic Invocation Interface). To use this support, you must not instantiate a foreign ORB inside the server. This will not yield any of the integration benefits of using the WebLogic ORB.
WebLogic Server also provides basic support for inbound CORBA calls as an alternative to hosting an ORB inside the server. This can be achieved by using ORB.connect()
to publish a CORBA server inside WebLogic Server. The easiest way to achieve this is to write an RMI-object which implements a CORBA interface. Given the MySVC examples above:
.
.
.
class MySvcImpl implements MvSvcOperations, Remote
{
public void do_something_remote() {}
public static main() {
MySvc svc = new MySvcTie(this);
InitialContext ic = new InitialContext();
((ORB)ic.lookup("java:comp/ORB")).connect(svc);
ic.bind("where", svc);
}
}
.
.
.
When registered as a startup class, the CORBA service will be available inside WebLogic Server`s CosNaming service at the location "where".
CORBA Object Type support has the following limitations:
ORB.connect()
result in a second object hosted inside the server. It is important that you use ORB.disconnect()
to remove the object when it is no longer needed.
You can implement Enterprise JavaBeans that use RMI over IIOP to provide EJB interoperability in heterogeneous server environments:
When using CORBA/IDL clients the sources of the mapping information are the EJB classes as defined in the Java source files. WebLogic Server provides the weblogic.appc
utility for generating required IDL files. These files represent the CORBA view into the state and behavior of the target EJB. Use the weblogic.appc
utility to:
The weblogic.appc
utility supports a number of command qualifiers. See Procedure for Developing a CORBA/IDL Client in Programming Stand-alone Clients.
Resulting files are processed using the compiler, reading source files from the idlSources
directory and generating CORBA C++ stub and skeleton files. These generated files are sufficient for all CORBA data types with the exception of value types (see see "Limitations of WebLogic RMI over IIOP" in Programming WebLogic RMI for more information). Generated IDL files are placed in the idlSources
directory. The Java-to-IDL process is full of pitfalls. Refer to the Java Language Mapping to OMG IDL specification. Also, Sun has an excellent guide, "Enterprise JavaBeansTM Components and CORBA Clients: A Developer Guide".
The following is an example of how to generate the IDL from a bean you have already created:
> java weblogic.appc -compiler javac -keepgenerated
-idl -idlDirectory idlSources
build\std_ejb_iiop.jar
%APPLICATIONS%\ejb_iiop.jar
After this step, compile the EJB interfaces and client application (the example here uses a CLIENT_CLASSES and APPLICATIONS target variable):
> javac -d %CLIENT_CLASSES% Trader.java TraderHome.java
TradeResult.java Client.java
Then run the IDL compiler against the IDL files built in the step where you used weblogic.appc
, creating C++ source files:
>%IDL2CPP% idlSources\examples\rmi_iiop\ejb\Trader.idl
. . .
>%IDL2CPP% idlSources\javax\ejb\RemoveException.idl
Now you can compile your C++ client.
For an in-depth look of how EJB's can be used with RMI-IIOP see the WebLogic Server RMI-IIOP examples, located in your installation inside the SAMPLES_HOME
/server/examples/src/examples/iiop
directory.
WebLogic Server's default garbage collection causes unused and unreferenced server objects to be garbage collected. This reduces the risk running out of memory due to a large number of unused objects. This policy can lead to NoSuchObjectException
errors in RMI-IIOP if a client holds a reference to a remote object but does not invoke on that object for a period of approximately six (6) minutes. Such exceptions should not occur with EJBs, or typically with RMI objects that are referenced by the server instance, for instance via JNDI.
The J2SE specification for RMI-IIOP calls for the use of the exportObject()
and unexportObject()
methods on javax.rmi.PortableRemoteObject
to manage the lifecycle of RMI objects under RMI-IIOP, rather than Distributed Garbage Collection (DGC). Note however that exportObject()
and unexportObject()
have no effect with WebLogic Server's default garbage collection policy. If you wish to change the default garbage collection policy, please contact BEA technical support.