Author Bio: Thomas Køcks Nielsen has been focusing on Portal development and Websphere infrastructure projects for the past 3 years. Before that he has been developing Lotus Notes and Domino applications for more than 12 years. He is a Portal architect working in Denmark for JN Data, which handles the infrastructure for many of the banks in Denmark. His current projects include Websphere infrastructure projects, Portlet Factory projects and WCM. Thomas is a certified Notes, web and Java developer. He can be reached at tkn@lotusdomino.dk.
Organizations tend to have more and more complex Enterprise infrastructure these days, making it more necessary to communicate and transfer secure data across platforms.
Typically, when you think about accessing data, you think of it as methods or procedures fetching and setting data, which are accessible on the server in your request. You tend to communicate using TCP or perhaps RPC. However a more streamlined, more flexible and easier way is to set up RMI (Remote Method Invocation) and then use EJB (Enterprise Java Beans) components to access the data.
Let’s have a look at these two terms:
- EJB is a component that is created, controlled and destroyed by the J2EE container which it lives in. A client that calls the component will not need to know what work is carried out. As far as the client is concerned it is talking directly with a remote component that supports a defined set of methods.
- RMI makes it possible to call functions across different JVMs across different computers. It is even possible to pass objects to a foreign machine, allowing dynamic loading of new classes. You define the interfaces locally, but the implementations of these interfaces are done remotely, hence you can say that the client knows of the interface, but not of the implementation.
 |
How RMI works (click image to enlarge)
|
One of the main uses of EJBs is to provide the business logic that sits behind web components, or EAI (Enterprise Application Integration) applications using the EJBs as processing and mappings between different applications, i.e., encapsulation of the business logic. EJB architecture allows use of different communication protocols simultaneously
As an alternative to RMI, you can establish communication with web services using these techniques:
- TCP sockets. Drawback: developer needs to implement custom protocols for the components. Not possible to reference remote objects.
- RPC (Remote Procedure Calls). Drawback: Not possible to reference remote objects.
- CORBA. Drawback: More complex than RMI, different language skills needed.
- RMI. Drawback: only possible in Java-2-Java systems. Uses Java serialization to pack objects.
If you are thinking, why change direction in the way I work, why go through all this? We might as well use webservices – with XML over http? If you try or have tried both, you will see a remarkable difference in speed, RMI is much faster than traditional communication with xml over http – which is what many companies tend to do these days.
RMI will handle:
- threads for you
- sockets for you
- a nice garbage collection of lost clients
- marshall objects for you
- dynamic loading of classes
Java using RMI can be headlined with the following:
- the server interface (used by the stub/skeleton when compiling the client stub)
- the server implementation (the java server methods)
- a server skeleton and the client stub (acts as the interface between the RMI registry and the server object)
- the client implementation
In the following we will go through a configuration between two WAS/WPS cells, that enables us to do cross cell EJB calls.
Further we will briefly touch on how an EJB bean and servlet could look, and how to test that the configuration is setup correctly.
WAS configuration
Install your application on the source and target servers. As you will see later, we have used a bean and a servlet.
For the purpose of this article, we have used a server called jbaix142 (WPS) as the source server and jbaix104 (WAS) as the target server.
The bean and servlet that we have deployed, will test that everything works as designed with RMI. Do note that the bean and servlet that we use is the same for both the source and target server.
- Install and verify the RMI application from the WAS source and target deployment manager (dmgr). Check that the application is running, if not start it.
- Check that the correct virtual host (vhost) for your environment is applied to the application. This is done in the application settings, under “web module properties”.
- In the application settings under “Detail properties”, set the “security role to user/group mapping” to “All Authenticated in Trusted Realms”. Making it accept the realms that we add in the global security section mentioned below.
 |
The setting that makes the application accept all trusted realms. (click image to enlarge)
|
Certificates
Establish common certificates between the cells.
- Extract certificates from the target server (truststore in use).
From the dmgr locate the truststore in “Security / SSL certificate and key management / Key stores and certificates”.
If the application is running on i.e. node: jbaix142 and dmgr: jbaix141, then the certificate needs to be exported for both jbaix142 and jbaix141.
You extract the certificates by going into the dmgr console, locating the truststore that contains the certificates for jbaix141 and jbaix142, select these and click the extract button. The certificates are extracted to the file system on the server.
- Using add certificate - import the certificates on the source server – into the truststore for the cell, in our example jbaix104.
Note that if the nodes in the cell are on different LPARs/servers, you will need to verify that the keys are correctly propogated to each node’s truststore.
You can use “ikeyman” – IBM Key Manager to verify the content of the truststores, on each server.
If they are not propogated correctly, you will either need to import the keys separately (using i.e. “ikeyman”) or copy the entire truststore (make sure that the truststores are indentical except for the new keys - before importing).
You could also use the feature “Retrieve from port” in the signer certificates section of the trust store, to retrieve certificates. But also here it is necessary to check the truststore, to make sure that the certificates are correctly retrieved.
 |
The signer certificates, and the area where you can retrieve certificates. (click image to enlarge)
|
LTPA
Make sure that authentication mechanisms match, by exchanging LTPA keys, and make sure to disable automatic key generation on both servers. If you do not do disable this, you risk losing the imported keys.
- Make sure that the nodes are in sync. You can monitor this in the “System Administration / Nodes” section in the dmgr.
- Export the LTPA key from the source server. This is done by locating the LTPA section, under “Global security” in the dmgr console.
- Import the LTPA key to the target server, again from the LTPA section in “Global security”.
- After importing the key, again - make sure that the nodes are in sync. If they are not it is likely that you will need to do an offline sync.
Follow: http://www-01.ibm.com/support/docview.wss?rs=180&uid=swg21405907 to manually sync the nodes.
Global security
Set the global security to required SSL.
- In “Global security”, set the following in CSIv2 Transport layer section. Outbound for source server, inbound for target server.
- *Client certificate authentication = Never
- *Transport = SSL-require
- On the source server, set the “trusted authentication realms – outbound” to the target realm. Again this is found in the “Global security/CSIv2 Transport layer section”.
- On the target server, set the “trusted authentication realms – inbound” to the source realm. Again this is found in the “Global security/CSIv2 Transport layer section”.
The realm is typically the ldap server including the port number, e.g., ldapapptest.corp.sim.net:636. You can find the realm in the “global security” section in the deployment manager console. The section “User account repository” contains a configure button, pressing this will take you to the “Standalone LDAP registry” (if this is what is configured on the WAS server). In here you have both the host name and the port name, which you can use as the realm above.
Restart
A restart is necessary due to major changes to configuration in dmgr.
- Restart dmgr
- Restart cluster/servers
- Make sure that the nodes are in sync
 |
Always make sure that the nodes are in sync (click image to enlarge) |
Environment
The environment we have used to set up cross cell EJB calls, are
- WAS 7.0.0.9 on AIX, with two nodes: jbaix104 and jbaix105, where the deployment manager is jbaix106.
- WPS 6.1.5 (WAS 7.0.0.9) on AIX, with two nodes: jbaix142 and jbaix143, where the deployment manager is jbaix141.
In the environment above, we would like to call methods on jbaix104, which will then call jbaix142 remotely. The call should be done securely between the nodes.
For this purpose we have created a bean and a servlet that will test secure cross cell EJB calls.
The servlet verifies that it is possible to invoke EJBs at an application installed at another Websphere cell. It checks security and transaction propagations.
It is the servlet that performs the test. The servlet takes a single http parameter named corbaloc. This parameter specifies a corba location which is used for looking up the remote bean. For example:
https://jbaix142.jyskebank.dk:56004/jb.itu.ti.rmitest.web/test?corbaloc=corbaloc: iiop:jbaix104.jyskebank.dk:20102
This URL invokes beans at the environment server jbaix104 which use 20102 as bootstrap address. If you do not specify the corbaloc parameter the application calls the bean internally – in this case on jbaix142. By running it locally on jbaix142 you can verify that the application performs as needed, before trying to execute remotely on jbaix104.
The application (session bean) is rather simple. The RMI client checks the response from the method, where the method callMeTransactionalAndSecure is called with an authenticated user and run in the context of a transaction.
The servlet that is deployed on the servers is similar to the example below, it basically invokes the bean on the server specified in the corbaloc parameter, and prints the result using the java printwriter.
 |
| Click image to enlarge |
As you can see, the interface or proxy defined in the RMITestInvoker bean does not contain any method implementation:
public interface Hello
{
public abstract String callMeTransactionalAndSecure(String s);
public abstract String callMeNonTransactionalAndSecure(String s);
public abstract String callMeNonTransactionalAndUnsecure(String s);
}
and the RMITestInvoker bean (the implementation of the interface),
protected Collection invokeMethod(Hello bean)
{
Collection result = new ArrayList();
try
{
String msg = bean.callMeNonTransactionalAndUnsecure((new LocalHost()).getName());
System.out.println((new StringBuilder()).append("Got: ").append(msg).toString());
result.add(new RMITestInvoker.Status("Non transactional and unsecure", true, msg));
}
catch(Throwable t)
{
result.add(new RMITestInvoker.Status("Non transactional and unsecure", false, t.getMessage()));
}
try
{
String msg = bean.callMeNonTransactionalAndSecure((new LocalHost()).getName());
System.out.println((new StringBuilder()).append("Got: ").append(msg).toString());
result.add(new RMITestInvoker.Status("Non transactional and secure", true, msg));
}
catch(Throwable t)
{
result.add(new RMITestInvoker.Status("Non transactional and secure", false, t.getMessage()));
}
try
{
String msg = bean.callMeTransactionalAndSecure((new LocalHost()).getName());
System.out.println((new StringBuilder()).append("Got: ").append(msg).toString());
result.add(new RMITestInvoker.Status("Transactional and secure", true, msg));
}
catch(Throwable t)
{
result.add(new RMITestInvoker.Status("Transactional and secure", false, t.getMessage()));
}
return result;
}
Basically the servlet invokes the bean, and just prints the testcases from our bean, and we use the following URL to invoke the servlet (and bean),
https://jbaix142.jyskebank.dk:56004/jb.itu.ti.rmitest.web/test?corbaloc=corbaloc:iiop:jbaix104.jyskebank.dk:20102
Which calls the methods on jbaix104, where as,
https://jbaix142.jyskebank.dk:56004/jb.itu.ti.rmitest.web
will obviously call the methods locally on the server jbaix142.
In our example, the URL above will give us the following result:
 |
Example result (click image to enlarge)
|
Of course, the above pieces of code are just part of the deployed application. It is, however, the essential part which enables you to develop your own test application. It is beyond the scope of this article to go through the entire code for the sample application.
Conclusion
It might be difficult or demanding to setup and configure RMI, but when it has been setup, it is easy to implement and change methods that you are able to call across cells.
As you have learned, the main disadvantage of using RMI is that it is strictly java. Beyond that, this drawback is far outweighed by the advantages.
There are an alternative to RMI, alled Jini, which is a more advanced version of RMI. It provides more mechanisms for the distributed object.
You can read more about Jini at http://www.jini.org/wiki/Main_Page