Accessing Java from ASP (Zero Client Installation)

Java/J2EE COM Interoperability Products Page

This example demonstrates how to access Java from ASP using J-Integra®'s zero client installation. J-Integra® for COM is a Java interoperability component that bridges Java and ASPs. It provides bi-directional access of Java objects and COM components.

In this article I will show you how you can access Java objects (including EJBs) running on any Operating System from COM clients running on a standard Microsoft Windows NT (SP4 or greater) or Windows 2000 machine. There is zero deployment overhead: you will not have to install any software at all on the Windows client machine.

The example uses Visual BASIC as the COM client, although the same code could be used from environments such as Active Server Pages. On the Java side it uses the J-Integra® pure Java-COM bridge from Intrinsyc®. You will need the jintegra.jar file from the kit on the machine running the Java objects that are accessed from COM. Since this is a pure Java jar file, this machine can be running any operating system using any JVM.

How does it work?

You use a J-Integra® tool (GetJvmMoniker) to generate a COM objref moniker. This is a long string which represents a reference to a COM object. You can use this string from COM clients to dynamically access a COM object.

In our case the objref moniker string generated by GetJvmMoniker references a JVM Java object (an instance of a J-Integra® built-in Java class) sitting in a JVM running somewhere. This JVM object can be used to instanciate and access instances of other Java classes in the JVM.

Steps

The following steps are involved:

  1. Display the JVM's moniker

  2. Start the JVM

  3. Access Java objects fron the Windows VB client by using the moniker

Display the JVM's moniker

  1. On any machine that has the jintegra.jar file from the J-Integra® kit on it, set your CLASSPATH to include jintegra.jar.

  2. Then run the com.linar.jintegra.GetJvmMoniker Java class, specifying the IP address or full DNS name of the machine running the JVM in which Java objects will be accessed, and a free TCP/IP port number as parameters:

    java com.linar.jintegra.GetJvmMoniker mymachine.mycompany.com 3000
  3. Note: If you run the COM client and it crashes with Automation error: The object exporter specified was not found, then you must run the GetJvmMoniker command with the IP address of the machine hosting the JVM (and not the full DNS name).

  4. You will see a long message displayed which shows the objref moniker and explains how to use it. The full text is also copied to your clipboard:

Start the JVM

  1. Create a file called TestJvm.java with the following contents:

    import com.linar.jintegra.Jvm;
    
    public class TestJvm {
        public static void main(java.lang.String[] args) throws Exception {
             // com.linar.jintegra.Log.logImmediately(3, "jintegra.log");
             Jvm.register("ajvm");
             while (true) {
          // So that the JVM does not terminate immediately
                  Thread.sleep(10000);
        }
      }
    }

  2. Compile the file using javac TestJvm.java then run it using java -DJINTEGRA_DCOM_PORT=3000 TestJvm

Create the Windows VB client

  1. On the Windows client machine, start Visual BASIC and create a new project of type "Standard EXE".

  2. Double-click on the form that is displayed to edit the code that is run when the form is first displayed when you run the program.

  3. Any Java object accessible from your CLASSPATH can be accessed from your VB or ASP. Enter this code to start with, replacing "objref:...:" with the actual text displayed when you started the JVM above:

    VB:

    Private Sub Form_Load()
      Set
    jvm = GetObject("objref:...:")
      Set
    vector = jvm.get("java.util.Vector")
      vector.addElement "hello"
      vector.addElement "goodbye"
      MsgBox vector

      For Each
    elt In vector
         MsgBox elt
      Next
    End Sub

    ASP:

    <%@ LANGUAGE = VBScript %>
    <HTML>
    <HEAD>
    <TITLE>Accessing Java classes from ASP using any JVM running anywhere</TITLE>
    <BODY>
    <%
    Set jvm = GetObject("objref:...:")
    Set vector = jvm.get("java.util.Vector")
    vector.addElement "hello"
    Response.write("vector = " & vector & "<BR>")
    %>
    </BODY>
    </HTML>
  4. When you run your VB code you should see three pop-ups, the first being the result of doing Vector.toString() and then the two elements in the vector:


    When you run your ASP you should see this page:

  5. You can use the call to jvm.get("java.util.Vector") to get hold of instances of any public class which has a public default constructor, and you can invoke all public methods and access all public fields, including static ones.

Accessing EJBs

You probably have a few questions at this point, such as What was the point of doing the Jvm.register("aJvm") in the Java code? The answer is that it was really only there to initialise the J-Integra® runtime, however it can also be used to intercept the instantiation request from the COM client, and to return objects that you manufacture:

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

import com.linar.jintegra.*;

public class TestJvm {
  public static void main(java.lang.String[] args) throws Exception {
    Jvm.register("ajvm", new MyInstanciator());
    while (true) {
      // So that the JVM does not terminate immediately
      Thread.sleep(10000);
    }
  }
}

class MyInstanciator implements Instanciator {
  Context ctx;

  MyInstanciator() throws NamingException {
    Hashtable env = new Hashtable(11);
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://... TBS ...");
    ctx = new InitialContext(env);
  }

  public Object instanciate(String javaClass) throws AutomationException {
    try {
      // First try to instantiate it as a normal Java class
        try {
          return Class.forName(javaClass).newInstance();
        } catch (Throwable t) {
          t.printStackTrace();
          throw new AutomationException(t);
        }
        // If that fails to a JNDI lookup
        return ctx.lookup(javaClass);
    } catch (Throwable t) {
       t.printStackTrace();
       throw new AutomationException(t);
    }
  }
}

Then in your VB code you can use:
Set anObect = jvm.get("aJvm:cn=ObjectName");

This will cause your instantiation code to be invoked in order to return the object. You can do anything you want in there to instantiate the object.

Once you have access to an Java object from COM you can also access it using early binding (vtable access). Simply add a reference the appropriate type library (either an existing one, or one generated through J-Integra®'s java2com tool), and then access the Java object through the appropriate type in the type library. More explanation will follow in the next release of J-Integra®, however if you walk through some of the step-by-step early-binding examples in the J-Integra® documentation, this should be fairly easy to work out.