bea.com | products | dev2dev | support | askBEA |
|
e-docs > WebLogic Server > Programming WebLogic RMI over IIOP > Using RMI over IIOP Programming Models to Develop Applications |
Programming WebLogic RMI over IIOP |
Using RMI over IIOP Programming Models to Develop Applications
The following sections describe how to use various programming models to develop RMI-IIOP applications:
Overview of RMI-IIOP Programming Models
IIOP is a robust protocol that is supported by numerous vendors and is designed to facilitate interoperation between heterogeneous distributed systems. Two basic programming models are associated with RMI-IIOP: RMI-IIOP with RMI clients and RMI-IIOP with IDL clients. Both models share certain features and concepts, including the use of a Object Request Broker (ORB) and the Internet InterORB Protocol (IIOP). However, the two models are distinctly different approaches to creating a interoperable environment between heterogeneous systems. Simply, IIOP can be a transport protocol for distributed applications with interfaces written in either IDL or Java RMI. When you program, you must decide to use either IDL or RMI interfaces; you cannot mix them.
Several factors determine how you will create a distributed application environment. Because the different models for employing RMI-IIOP share many features and standards, it is easy to lose sight of which model you are following.
The following table lists the types of clients supported in a WebLogic Server environment, and their characteristics, features, and limitations. The table includes T3 and CORBA client options, as well as RMI-IIOP alternatives.
Table 2-1 WebLogic Server Client Types and Features
RMI is a Java-to-Java model of distributed computing. RMI enables an application to obtain a reference to an object that exists elsewhere in the network All RMI-IIOP models are based on RMI; however, if you follow a plain RMI model without IIOP, you cannot integrate clients written in languages other than Java. You will also be using T3, a proprietary protocol, and have WebLogic classes on your client. For information on developing RMI applications, see Using WebLogic RMI
RMI over IIOP with RMI clients combines the features of RMI with the standard IIOP protocol and allows you to work completely in the Java programming language. RMI-IIOP with RMI Clients is a Java-to-Java model, where the ORB is typically a part of the JDK running on the client. Objects can be passed both by reference and by value with RMI-IIOP.
J2SE clients is oriented towards the J2EE programming model; it combines the capabilities of RMI with the IIOP protocol. If your applications are being developed in Java and you wish to leverage the benefits of IIOP, you should use the RMI-IIOP with RMI client model. Using RMI-IIOP, Java users can program with the RMI interfaces and then use IIOP as the underlying transport mechanism. The RMI client runs an RMI-IIOP-enabled ORB hosted by a J2EE or J2SE container, in most cases a 1.3 or higher JDK. Note that no WebLogic classes are required, or automatically downloaded in this scenario; this is a good way of having a minimal client distribution. You also do not have to use the proprietary t3 protocol used in normal WebLogic RMI, you use IIOP, which based on an industry, not proprietary, standard.
This client is J2SE-compliant, rather than J2EE-compliant, hence it does not support many of the features provided for enterprise-strength applications. Depending on application requirements, this client may not provide required functionality. It does not support security, transactions, or JMS.
Procedure for Developing J2SE Client
To develop an application using RMI-IIOP with an RMI client:
This remote interface may not require much code. All you need are the method signatures for methods you want to implement in remote classes. For example, with the Ping example included in your Weblogic installation SAMPLES_HOME/server/src/examples/iiop/rmi/server/wls:
public interface Pinger extends java.rmi.Remote {
public void ping() throws java.rmi.RemoteException;
public void pingRemote() throws java.rmi.RemoteException;
public void pingCallback(Pinger toPing) throws java.rmi.RemoteException;
}
This class should implement the remote interface that you wrote, which means that you implement the method signatures that are contained in the interface. All the code generation that will take place is dependent on this class file. Typically, you configure your implementation class as a WebLogic startup class and include a main method that binds the object into the JNDI tree. Here is an excerpt from the implementation class developed from the previous Ping example:
public static void main(String args[]) throws Exception {
if (args.length > 0)
remoteDomain = args[0];
Pinger obj = new PingImpl();
Context initialNamingContext = new InitialContext();
initialNamingContext.rebind(NAME,obj);
System.out.println("PingImpl created and bound to "+ NAME);
}
$ java weblogic.rmic nameOfImplementationClass
In the case of the Pinger example, the nameOfImplementationClass is examples.iiop.rmi.server.wls.PingerImpl.
A stub is the client-side proxy for a remote object that forwards each WebLogic RMI call to its matching server-side skeleton, which in turn forwards the call to the actual remote object implementation. Note that the IIOP stubs created by the WebLogic RMI compiler are intended to be used with the JDK 1.3.1_01 or higher ORB. If you are using another ORB, consult the ORB vendor's documentation to determine whether these stubs are appropriate.
RMI clients access remote objects by creating an initial context and performing a lookup (see next step) on the object. The object is then cast to the appropriate type.
In obtaining an initial context, you must use com.sun.jndi.cosnaming.CNCtxFactory when defining your JNDI context factory. (WLInitialContextFactory is deprecated for this client in WebLogic Server 8.1) Use com.sun.jndi.cosnaming.CNCtxFactory when setting the value for the "Context.INITIAL_CONTEXT_FACTORY" property that you supply as a parameter to new InitialContext().
Note: The Sun JNDI client supports the capability to read remote object references from the namespace, but not generic Java serialized objects. This means that you can read items such as EJBHomes out of the namespace but not DataSource objects. There is also no support for client-initiated transactions (the JTA API) in this configuration, and no support for security. In the stateless session bean RMI Client example, the client obtains an initial context as is done below:
Obtaining an InitialContext:
* Using a Properties object as follows will work on JDK13
* clients.
*/
private Context getInitialContext() throws NamingException {
try {
// Get an InitialContext
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.cosnaming.CNCtxFactory");
h.put(Context.PROVIDER_URL, url);
return new InitialContext(h);
} catch (NamingException ne) {
log("We were unable to get a connection to the WebLogic server at "+url);
log("Please make sure that the server is running.");
throw ne;
}
/**
* This is another option, using the Java2 version to get an * InitialContext.
* This version relies on the existence of a jndi.properties file in
* the application's classpath. See
* Programming WebLogic JNDI for more information
private static Context getInitialContext()
throws NamingException
{
return new InitialContext();
}
RMI over IIOP RMI clients differ from regular RMI clients in that IIOP is defined as the protocol when obtaining an initial context. Because of this, lookups and casts must be performed in conjunction with the javax.rmi.PortableRemoteObject.narrow() method.
For example, in the RMI client stateless session bean example (the examples.iiop.ejb.stateless.rmiclient package included in your distribution), an RMI client creates an initial context, performs a lookup on the EJBean home, obtains a reference to an EJBean, and calls methods on the EJBean.
You must use the javax.rmi.PortableRemoteObject.narrow() method in any situation where you would normally cast an object to a specific class type. A CORBA client may return an object that doesn't implement your remote interface; the narrow method is provided by your orb to convert the object so that it implements your remote interface. For example, the client code responsible for looking up the EJBean home and casting the result to the Home object must be modified to use the javax.rmi.PortableRemoteObject.narrow() as shown below:
Performing a lookup:
/**
* RMI/IIOP clients should use this narrow function
*/
private Object narrow(Object ref, Class c) {
return PortableRemoteObject.narrow(ref, c);
}
/**
* Lookup the EJBs home in the JNDI tree
*/
private TraderHome lookupHome()
throws NamingException
{
// Lookup the beans home using JNDI
Context ctx = getInitialContext();
try {
Object home = ctx.lookup(JNDI_NAME);
return (TraderHome) narrow(home, TraderHome.class);
} catch (NamingException ne) {
log("The client was unable to lookup the EJBHome. Please
make sure ");
log("that you have deployed the ejb with the JNDI name
"+JNDI_NAME+" on the WebLogic server at "+url);
throw ne;
}
}
/**
* Using a Properties object will work on JDK130
* clients
*/
private Context getInitialContext() throws NamingException {
try {
// Get an InitialContext
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.cosnaming.CNCtxFactory");
h.put(Context.PROVIDER_URL, url);
return new InitialContext(h);
} catch (NamingException ne) {
log("We were unable to get a connection to the WebLogic
server at "+url);
log("Please make sure that the server is running.");
throw ne;
}
}
The url defines the protocol, hostname, and listen port for the WebLogic Server and is passed in as a command-line argument.
public static void main(String[] args) throws Exception {
log("\nBeginning statelessSession.Client...\n");
String url = "iiop://localhost:7001";
$ java -Djava.security.manager -Djava.security.policy=java.policy examples.iiop.ejb.stateless.rmiclient.Client iiop://localhost:7001
java -Djava.security.manager -Djava.security.policy==java.policy myclient
To narrow an RMI interface on a client the server needs to serve the appropriate stub for that interface. The loading of this class is predicated on the use of the JDK network classloader and this is not enabled by default. To enable it you set a security manager in the client with an appropriate java policy file. For more information on Java security, see Sun's site at http://java.sun.com/security/index.html. The following is an example of a java.policy file:
permission java.security.AllPermission;
Developing a J2EE Application Client (Thin Client)
A J2EE application client runs on a client machine and can provide a richer user interface than can be provided by a markup language. Application clients directly access enterprise beans running in the business tier, and may, as appropriate, communicate via HTTP with servlets running in the Web tier. An application client is typically downloaded from the server, but can be installed on a client machine.
Although a J2EE application client is a Java application, it differs from a stand-alone Java application client because it is a J2EE component, hence it offers the advantages of portability to other J2EE-compliant servers, and can access J2EE services.
The WebLogic Server application client is provided as a standard client and a JMS client, packaged as two separate jar files—wlclient.jar and wljmsclient.jar— in the /server/lib subdirectory of the WebLogic Server installation directory. Each jar is about 400 KB.
The thin client is based upon the RMI-IIOP protocol stack available in JDK 1.4.n. The basics of making RMI requests are handled by the JDK, enabling a significantly smaller client. Client-side development is performed using standard J2EE APIs, rather than WebLogic Server APIs.
The development process for a thin client application is the same is as for other J2EE applications. The client can leverage standared J2EE artifacts such as InitialContext, UserTransaction, and EJBs. The WebLogic Server thin client supports these values in the protocol portion of the URL—iiop, iiops, http, https, t3, and t3s—each of which can be selected by using a different URL in InitialContext. Regardless of the URL, IIOP is used. URLs with t3 or t3s use iiop and iiops respectively. http is tunnelled iiop, https is iiop tunnelled over https.
Server-side components are deployed in the usual fashion. Client stubs can be generated at either deployment time or runtime.To generate stubs when deploying, run appc with the -iiop and -clientJar options to produce a client jar suitable for use with the thin client. Otherwsie, WebLogic Server will generate stubs on demand at runtimeand serve them to the client. Downloading of stubs by the client requires that a suitable security manager be installed. The thin client provides a default lightp-weight security manager. For rigorous security requirements, a different security manager can be installed with the command line options -Djava.security.manager -Djava.security.policy==policyfile. Applets use a different security manager which already allows the downloading of stubs.
The WebLogic thin client jar leverages features new to J2SE 1.4, so the JRE 1.4 is required. Although the thin-client will work with JRE 1.4.0, use of JRE 1.4.1_02 is recommended, due to bug fixes that affect the thin client.
Note: Long running clients should use JRE 1.4.1_03 when it is released.
The thin client jar replaces some classes in weblogic.jar, if both the full jar and the thin client jar are in the CLASSPATH, the thin client jar should be first in the path. Note however that weblogic.jar is not required to support the thin client. If desired, you can use this syntax to run with an explicit CLASSPATH:
java -classpath "<WL_HOME>/lib/wlclient.jar;<CLIENT_CLASSES>" your.app.Main
Note: wljmsclient.jar has a reference to wlclient.jar so it is only necessary to put one or the other Jar in the CLASSPATH.
Do not put the thin-client jar in the server-side CLASSPATH.
The thin client jar contains the neccessary J2EE interface classes, such as javax.ejb, so no other jar files are neccessary on the client.
Procedure for Developing J2EE Application Client (Thin Client)
To develop a J2EE Application Client:
This remote interface may not require much code. All you need are the method signatures for methods you want to implement in remote classes. For example, with the Ping example included in your Weblogic installation:
SAMPLES_HOME/server/src/examples/iiop/rmi/server/wls:
public interface Pinger extends java.rmi.Remote {
public void ping() throws java.rmi.RemoteException;
public void pingRemote() throws java.rmi.RemoteException;
public void pingCallback(Pinger toPing) throws java.rmi.RemoteException;
}
This class should implement the remote interface that you wrote, which means that you implement the method signatures that are contained in the interface. All the code generation that will take place is dependent on this class file. Typically, you configure your implementation class as a WebLogic startup class and include a main method that binds the object into the JNDI tree. Here is an excerpt from the implementation class developed from the previous Ping example:
public static void main(String args[]) throws Exception {
if (args.length > 0)
remoteDomain = args[0];
Pinger obj = new PingImpl();
Context initialNamingContext = new InitialContext();
initialNamingContext.rebind(NAME,obj);
System.out.println("PingImpl created and bound to "+ NAME);
}
Note: If you plan on donloading stubs, it is not necessary to run rmic.
$ java weblogic.rmic -iiop nameOfImplementationClass
In the case of the Pinger example, the nameOfImplementationClass is examples.iiop.rmi.server.wls.PingerImpl.
To generate stubs when deploying, run appc with the -iiop and -clientJar options to produce a client jar suitable for use with the thin client.. Otherwise, WebLogic Server will generate stubs on demand at runtime and serve them to the client.
A stub is the client-side proxy for a remote object that forwards each WebLogic RMI call to its matching server-side skeleton, which in turn forwards the call to the actual remote object implementation.
RMI clients access remote objects by creating an initial context and performing a lookup (see next step) on the object. The object is then cast to the appropriate type.
In obtaining an initial context, you must use weblogic.jndi.WLInitialContextFactory when defining your JNDI context factory. Use this class when setting the value for the "Context.INITIAL_CONTEXT_FACTORY" property that you supply as a parameter to new InitialContext().
RMI over IIOP RMI clients differ from regular RMI clients in that IIOP is defined as the protocol when obtaining an initial context. Because of this, lookups and casts must be performed in conjunction with the javax.rmi.PortableRemoteObject.narrow() method.
For example, in the RMI client stateless session bean example (the examples.iiop.ejb.stateless.rmiclient package included in your distribution), an RMI client creates an initial context, performs a lookup on the EJBean home, obtains a reference to an EJBean, and calls methods on the EJBean.
You must use the javax.rmi.PortableRemoteObject.narrow() method in any situation where you would normally cast an object to a specific class type. A CORBA client may return an object that doesn't implement your remote interface; the narrow method is provided by your orb to convert the object so that it implements your remote interface. For example, the client code responsible for looking up the EJBean home and casting the result to the Home object must be modified to use the javax.rmi.PortableRemoteObject.narrow() as shown below:
Performing a lookup:
/**
* RMI/IIOP clients should use this narrow function
*/
private Object narrow(Object ref, Class c) {
return PortableRemoteObject.narrow(ref, c);
}
/**
* Lookup the EJBs home in the JNDI tree
*/
private TraderHome lookupHome()
throws NamingException
{
// Lookup the beans home using JNDI
Context ctx = getInitialContext();
try {
Object home = ctx.lookup(JNDI_NAME);
return (TraderHome) narrow(home, TraderHome.class);
} catch (NamingException ne) {
log("The client was unable to lookup the EJBHome. Please
make sure ");
log("that you have deployed the ejb with the JNDI name
"+JNDI_NAME+" on the WebLogic server at "+url);
throw ne;
}
}
/**
* Using a Properties object will work on JDK130
* clients
*/
private Context getInitialContext() throws NamingException {
try {
// Get an InitialContext
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, url);
return new InitialContext(h);
} catch (NamingException ne) {
log("We were unable to get a connection to the WebLogic
server at "+url);
log("Please make sure that the server is running.");
throw ne;
}
}
The url defines the protocol, hostname, and listen port for the WebLogic Server and is passed in as a command-line argument.
public static void main(String[] args) throws Exception {
log("\nBeginning statelessSession.Client...\n");
String url = "iiop://localhost:7001";
$ java -Djava.security.manager -Djava.security.policy=java.policy examples.iiop.ejb.stateless.rmiclient.Client iiop://localhost:7001
In WebLogic Server 7.0, support for a "fat" RMI-IIOP client—referred to as the WLS-IIOP Client—was introduced. The WLS-IIOP Client supports clustering.
To support WLS-IIOP clients, you must:
Otherwise, the procedure for developing a WLS-IIOP Client is the same as the procedure described in Developing a J2SE Client.
Note: In WebLogic Server 8.1 you do not need to use the
-D weblogic.system.iiop.enableClient=true command line option to to enable client access when starting the client. By default, if you use weblogic.jar, enableClient is set to true.
RMI over IIOP with CORBA/IDL clients involves an Object Request Broker (ORB) and a compiler that creates an interoperating language called IDL. C, C++, and COBOL are examples of languages that ORB's may compile into IDL. A CORBA programmer can use the interfaces of the CORBA Interface Definition Language (IDL) to enable CORBA objects to be defined, implemented, and accessed from the Java programming language.
Guidelines for Developing a CORBA/IDL Client
Using RMI-IIOP with a CORBA/IDL client enables interoperability between non-Java clients and Java objects. If you have existing CORBA applications, you should program according to the RMI-IIOP with CORBA/IDL client model. Basically, you will be generating IDL interfaces from Java. Your client code will communicate with WebLogic Server through these IDL interfaces. This is basic CORBA programming.
The following sections provide some guidelines for developing RMI-IIOP applications with CORBA/IDL clients.
For further reference see the following Object Management Group (OMG) specifications:
Working with CORBA/IDL Clients
In CORBA, interfaces to remote objects are described in a platform-neutral interface definition language (IDL). To map the IDL to a specific language, the IDL is compiled with an IDL compiler. The IDL compiler generates a number of classes such as stubs and skeletons that the client and server use to obtain references to remote objects, forward requests, and marshall incoming calls. Even with IDL clients it is strongly recommended that you begin programming with the Java remote interface and implementation class, then generate the IDL to allow interoperability with WebLogic and CORBA clients, as illustrated in the following sections. Writing code in IDL that can be then reverse-mapped to create Java code is a difficult and bug-filled enterprise and WebLogic does not recommend doing this.
The following figure shows how IDL takes part in a RMI-IIOP model:
Figure 2-1 IDL Client (Corba object) relationships
In WebLogic RMI, interfaces to remote objects are described in a Java remote interface that extends java.rmi.Remote. The Java-to-IDL mapping specification defines how an IDL is derived from a Java remote interface. In the WebLogic RMI over IIOP implementation, you run the implementation class through the WebLogic RMI compiler or WebLogic EJB compiler with the -idl option. This process creates an IDL equivalent of the remote interface. You then compile the IDL with an IDL compiler to generate the classes required by the CORBA client.
The client obtains a reference to the remote object and forwards method calls through the stub. WebLogic Server implements a CosNaming service that parses incoming IIOP requests and dispatches them directly into the RMI runtime environment.
The following figure shows this process.
Figure 2-2 WebLogic RMI over IIOP object relationships
The Objects-by-Value specification allows complex data types to be passed between the two programming languages involved. In order for an IDL client to support Objects-by-Value, you develop the client in conjunction with an Object Request Broker (ORB) that supports Objects-by-Value. To date, relatively few ORBs support Objects-by-Value correctly.
When developing an RMI over IIOP application that uses IDL, consider whether your IDL clients will support Objects-by-Value, and design your RMI interface accordingly. If your client ORB does not support Objects-by-Value, you must limit your RMI interface to pass only other interfaces or CORBA primitive data types. The following table lists ORBs that BEA Systems has tested with respect to Objects-by-Value support:
supported (we have encountered issues with this implementation) |
For more information on Objects-by-Value, see Limitations of Passing Objects by Value
Procedure for Developing a CORBA/IDL Client
To develop an RMI over IIOP application with CORBA/IDL:
The required stub classes will be generated when you compile the IDL file. For general information on the these compilers, refer to Using WebLogic RMI and BEA WebLogic Server Enterprise JavaBeans. Also reference the Java IDL specification at Java Language Mapping to OMG IDL Specification .
The following compiler options are specific to RMI over IIOP:
The options are applied as shown in this example of running the RMI compiler:
> java weblogic.rmic -idl -idlDirectory /IDL rmi_iiop.HelloImpl
The compiler generates the IDL file within sub-directories of the idlDirectoy according to the package of the implementation class. For example, the preceding command generates a Hello.idl file in the /IDL/rmi_iiop directory. If the idlDirectory option is not used, the IDL file is generated relative to the location of the generated stub and skeleton classes.
The IDL file generated by the WebLogic compilers contains the directives: #include orb.idl. This IDL file should be provided by your ORB vendor. An orb.idl file is shipped in the /lib directory of the WebLogic distribution. This file is only intended for use with the ORB included in the JDK that comes with WebLogic Server.
IDL clients are pure CORBA clients and do not require any WebLogic classes. Depending on your ORB vendor, additional classes may be generated to help resolve, narrow, and obtain a reference to the remote class. In the following example of a client developed against a VisiBroker 4.1 ORB, the client initializes a naming context, obtains a reference to the remote object, and calls a method on the remote object.
Code segment from C++ client of the RMI-IIOP example
// string to object
CORBA::Object_ptr o;
cout << "Getting name service reference" << endl;
if (argc >= 2 && strncmp (argv[1], "IOR", 3) == 0)
o = orb->string_to_object(argv[1]);
else
o = orb->resolve_initial_references("NameService");
// obtain a naming context
cout << "Narrowing to a naming context" << endl;
CosNaming::NamingContext_var context = CosNaming::NamingContext::_narrow(o);
CosNaming::Name name;
name.length(1);
name[0].id = CORBA::string_dup("Pinger_iiop");
name[0].kind = CORBA::string_dup("");
// resolve and narrow to RMI object
cout << "Resolving the naming context" << endl;
CORBA::Object_var object = context->resolve(name);
cout << "Narrowing to the Ping Server" << endl;
::examples::iiop::rmi::server::wls::Pinger_var ping =
::examples::iiop::rmi::server::wls::Pinger::_narrow(object);
// ping it
cout << "Ping (local) ..." << endl;
ping->ping();
Notice that before obtaining a naming context, initial references were resolved using the standard Object URL (CORBA/IIOP 2.4.2 Specification, section 13.6.7). Lookups are resolved on the server by a wrapper around JNDI that implements the COS Naming Service API.
The Naming Service allows Weblogic Server applications to advertise object references using logical names. The CORBA Name Service provides:
WebLogic Server provides the ability to interoperate between WebLogic Server applications and Tuxedo services using RMI-IIOP. This includes calling EJBs and other applications on WebLogic from Tuxedo clients as well as other features.
The RMI-IIOP examples included in the samples/examples/iiop directory of your installation contain some samples of how to configure and set up your WebLogic Server to work with Tuxedo Servers and Tuxedo Clients.
WebLogic Tuxedo Connector provides interoperability between WebLogic Server applications and Tuxedo services. 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. 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, the WebLogic Tuxedo Connector allows you to leverage Tuxedo's highly scalable and reliable CORBA environment.
The following documentation provides information on the Weblogic Tuxedo Connector, as well as building CORBA applications on Tuxedo:
WebLogic Server 8.1 interoperates with the Tuxedo 8.0 C++ Client ORB. This client supports object by value and the CORBA Interoperable Naming Service (INS). Tuxedo release 8.0 RP 56 and above is required. WebLogic Server users should contact their BEA Service Representative for information on how to obtain the Tuxedo C++ Client ORB.
The following documentation provides information on how to use the WebLogic C++ Client with the Tuxedo C++ Client ORB:
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.
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 Limitations of WebLogic RMI-IIOP 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/src/examples/iiop directory.