Visual Basic Accessing EJBs Hosted in WebSphere Application Server

Java/J2EE COM Interoperability Products Page

Summary

This example shows you how to allow COM clients, such as Visual Basic clients, to access Enterprise JavaBeans (EJBs) hosted in the IBM WebSphere Application Server, using J-Integra®.

Introduction

To illustrate how easy it is to access EJBs hosted in IBM's WebSphere Application Server from COM clients using J-Integra®, we use an example. The example used in this article is based on the standard Account EJB sample that comes with the default installation of IBM's WebSphere Application Server Advanced Edition. In this example, IBM demonstrates a persistent entity bean that models banking accounts. Here, we'll use the same example but instead of using a Java servlet as the client, we use a Visual Basic client.

Prerequisites

  1. Download and install the IBM WebSphere 4.0 sample server. NOTE: You MUST use the IBM JDK that comes with WebSphere. This is due to the fact that WebSphere 4.0 uses a built in IBM Corba classes that do NOT interoperate with the SUN Corba classes.

  2. Download and install J-Integra®.

  3. Before trying to get the VB client working you MUST get the standard Account example from IBM working first.  Note that the Account sample uses a DB2 database to store persistent data so you'll need to make sure that DB2 is installed and set up correctly.  Once you have everything set up, try running the standard Account example.  Enter 1020 for the account number, click Savings, and enter a starting balance of 2000.  Click Create and a message at the bottom of the page  should tell you that account 1020 was created.  If not, please refer to IBM's documentation for information on how to set things up.

The Steps Involved

The example is divided into two parts:

  1. The first part describes the steps to be performed on the server machine on which WebSphere and J-Integra® are installed. This may be on any platform supporting WebSphere.

  2. The second part describes the steps to be performed on the client machine, which must be a Windows machine and must have Visual Basic installed. You may, of course, run both the client and server on the same machine.

The Server Machine

In order for the VB client to talk to the EJB, a bridging JVM will run, which the VB client talks to. It in turn talks to the EJB. Setup and run this bridging JVM on the same machine as the WebSphere Application Server.  

This is the code associated with the bridging JVM:

import javax.naming.*;
import java.util.Hashtable;

import com.linar.jintegra.*;

public class ComToWebSphere {

  public ComToWebSphere() {
  }

  public void registerJVMandSleep() {
    try {
      // For COM access to objects loaded via JNDI lookup
      Jvm.register("wsejb", new EjbInstanciator());
      while (true) {
        Thread.sleep(5000);
      }
    } catch (Exception eX) {
      System.err.println("Exception: " + eX.getMessage());
    }
  }

  class EjbInstanciator implements Instanciator {
    Context ctx;

    EjbInstanciator() throws NamingException {
      Hashtable env = new Hashtable(11);
      env.put(Context.INITIAL_CONTEXT_FACTORY,
        com.ibm.websphere.naming.WsnInitialContextFactory
      );
      env.put(Context.PROVIDER_URL, "iiop://localhost:900");
      ctx = new InitialContext(env);
    }

    public Object instanciate(String javaClass) throws AutomationException {
      try {
        System.err.println("Class requested is..." + javaClass);
        if (findSlash(javaClass)) {
          Object obj = ctx.lookup(javaClass);
          return obj;
        }
        return Class.forName(javaClass).newInstance();
      } catch (Throwable t) {
        t.printStackTrace();
        throw new AutomationException(new Exception("Unexpected: " + t));
      }
    }
  }

  protected boolean findSlash(String s) {
    char[] characters = s.toCharArray();
    for (int i = 0; i < characters.length; i++) {
      if (characters[i] == '/') {
        return true;
      }
    }
    return false;
  }

  public static void main(String[] args) {
    com.linar.jintegra.Log.logImmediately(3, "jintegra.log");
    ComToWebSphere bridge = new ComToWebSphere();
    bridge.registerJVMandSleep();
  }

}

If you are using WebSphere 5.1, use this code instead. Thanks to Joe Fraser for his input.

To setup and run the bridging JVM, follow these steps:

  1. Update your CLASSPATH environment variable to include the J-Integra® runtime (jintegra.jar) from the J-Integra® kit.  Create a new directory and in it a file called "COMtoWS.java".  Copy and paste the content from the above box into the file and compile it.  

  2. In the directory where COMtoWS.java is located, create another file called runjvm.bat.  Copy and paste the contents in the box from below into the file. Note that this script assumes that the WebSphere Application Server is installed on a machine called Jintegraserver1 and the WebSphere Application Server root directory is c:\WebSphere\AppServer.Also, it assumes that the J-Integra® runtime can be found at c:\jintegra\lib\jintegra.jar. If this isn't the case for you, you need to customize the script so that the information is correct for your setup.  To make it easier, the places to look out for have been highlighted in the script below. Once the script is setup correctly, you can simply type runjvm at the command prompt to start the bridging JVM.

This is the code associated with runjvm.bat:

@rem +--------------------------+
@rem | Run Account Application  |
@rem +--------------------------+
@echo off
setlocal

@rem +-------------------------------------------------------------+
@rem | Setup WAS_HOME and JAVA_HOME.                             |
@rem | This assumes you installed Java along with the App Server,  |
@rem | so that all JDK binaries, etc, will be under App Server     |
@rem | directories.                                                |
@rem +-------------------------------------------------------------+

SET COMPUTERNAME=JINTEGRASERVER1
SET WAS_HOME=C:\WebSphere\AppServer
SET JAVA_HOME= C:\WebSphere\AppServer\java

@rem +----------------------+
@rem | Setup the classpath. |
@rem +----------------------+

set WAS_CP=%WAS_HOME%\lib\websphere.jar;%WAS_HOME%\lib\ 

@rem +----------------------------------------------------------------------+
@rem | JDK assumed installed with App Server, under App Server directories. |
@rem | Pre-pend system PATH so that binaries for this JDK will be used.     |
@rem +----------------------------------------------------------------------+

set PATH=%JAVA_HOME%\bin;%PATH% 

@rem +--------------------------------------------------------------------------------+
@rem | Relevant enterprise beans must be deployed, and copies of resulting jar files  |
@rem | must be on the local machine, even if the actual App Server machine is remote. |
@rem +--------------------------------------------------------------------------------+

set JARS_NEEDED=%WAS_HOME%\installedApps\Samples.ear\AccountAndTransferEJBean.jar
set CLASSPATH=?; C:\jintegra\lib\jintegra.jar;%WAS_CP%;%JARS_NEEDED%;

@rem +-------------------------------+
@rem | Finally, run the bridging JVM.|
@rem +-------------------------------+

java -DJINTEGRA_DCOM_PORT=7051 COMtoWS

endlocal

Registering the JVM on the Windows client machine

The Client Machine

  1. Start up Visual BASIC, and create a new Standard EXE project. Create a form that looks like the figure below and use the specified names for the individual controls:

  2. Double-click Create, and enter the following code:

    Private Sub Command1_Click()
    Dim home As Object
    Dim balance As Integer
    balance = 3000
    Dim account As Object
    Dim key As Object 

    ' The Account is accessed via JNDI
    Set home = GetObject("wsejb:WSsamples/AccountHome")
    Set key = GetObject("wsejb:WebSphereSamples.AccountAndTransfer.AccountKey") 

    On Error Resume Next
    key.AccountID = Form1.AccountNum.Text
    Set account = home.findByPrimaryKey(key)
    If Err.Number <> 0 Then
        MsgBox "Could not find " + Form1.AccountNum.Text & " (" & Err.Description & ")"
    End If
    On Error GoTo 0 ' clear error trap 

    If Form1.Savings.Value = True Then
        accountType = 1     ' Savings account
        accountName = "Savings"
    Else
        accountType = 0     ' Checking account
        accountName = "Checking"
    End If 

    If account Is Nothing Then
        MsgBox "Created Account: " + Form1.AccountNum.Text + ", Type: " & accountName & ", Balance: " & Form1.StartBalance.Text
        Set account = home.Create(key, accountType, Form1.StartBalance.Text)
    Else
        balance = account.getBalance()
        MsgBox "Account " & Form1.AccountNum.Text & " already exists; balance is $" & account.getBalance()
    End If 

    End Sub


  3. When you run this client, enter an account number, select an account type, and enter a starting balance before clicking Create. The VB client will then talk to the EJB and return the relevant messages:

  4. Create a new account that doesn't exist yet.  Click Create.

  5. You receive a message saying the bank account doesn't yet exist. Click OK.

  6. Next you receive a message indicating that the new account is being created.

  7. If you try to create an account that already exists, this is the message you get.