Accessing unmodified Java 2 objects running on any OS from Active Server Pages

By Damian Mehers, Copyright (c) 2000-2001 Intrinsyc Software, Inc..

In this hands-on article you will see how you can easily access your unmodified Java classes running in any JVM (such as Sun's 1.2 JDK) from Active Server Pages programs. The article takes the form of a step-by-step tutorial, which pretty much anyone can try out. It should take you less than an hour to run through this example.

You will see how you can easily access local and remote Java classes running anywhere that supports a standard JVM, such as Java 2 on UNIX. You can access all public fields and methods (including static ones) in Java objects, without modifying them:

I'll then show you how you can use J-Integra's native mode which loads the JVM in-process into the ASP environment. Again all public methods and fields in any public Java class can be accessed:

The Java class you will be accessing

This is the demo class that will be accessed from ASP in this example:
public class DemoClass {
  // Public field
  public static String name = "damian";
  
  // Public method.  Shows use of standard Java types, and how an object reference
  // can be returned
  public java.util.Vector getValues() {
    System.out.println("getValues called");
    java.util.Vector values = new java.util.Vector();
    values.addElement("A String");
    values.addElement(new Double(9876.5432));
    values.addElement(this); // !!!
    values.addElement(new java.util.Date());
    return values;
  }
  
  // Taken from MS example
  public double CalcFV(double dblRate, double dblNPer, double dblPMT, 
                       double dblPv, boolean bType) {
    double dblRet, dblTemp, dblTemp2, dblTemp3;

    if(dblRate == 0.0) {
      dblRet = -dblPv - dblPMT * dblNPer;
    } else {
      dblTemp = (bType ? 1.0 + dblRate : 1.0);
      dblTemp3 = 1.0 + dblRate;
      dblTemp2 = Math.pow(dblTemp3, dblNPer);  
      dblRet = -dblPv * dblTemp2 - dblPMT * dblTemp * (dblTemp2 - 1.0) / dblRate;
    }

    return dblRet;
  }
}

This is the ASP code which will access it

This is the code using VBScript:

<%@ LANGUAGE = VBScript %>
<HTML><HEAD><TITLE>Accessing Java classes from ASP using any JVM running anywhere</TITLE>
<body>

<% 
' Create an instance of the DemoClass Java class, which can be sitting in
' any JVM on any OS, such as a JDK1.2 JVM on UNIX
' You can use Server.CreateObject() too (see below).
Set Demo = GetObject("java2:DemoClass")

' Invoke a method which performs a calculation
FVal = Demo.CalcFV(0.1, 12, -10, -19, 1)
Response.write("FVal = " & FVal & "<BR>")

' Invoke a method which returns another object.
Set aCollection = Demo.getValues()
For each value In aCollection ' !!! aCollection is a Java java.util.Vector.  Can you tell?
  Response.write("Value = " & value & "<BR>")
Next

' Finally access a public field (which happens to be static)
Response.write("Demo.name = " + Demo.name & "<BR>")
Demo.name = "Alfred"
Response.write("Updated Demo.name = " & Demo.name & "<BR>")
%>
</BODY>
</HTML>

If you prefer using JScript instead, here is the same ASP code but using JScript:

<%@ LANGUAGE = JScript %>
<HTML><HEAD><TITLE>Accessing Java classes from ASP using any JVM running anywhere</TITLE> 
<body>

<% 
// Create an instance of the DemoClass Java class, which can be sitting in
// any JVM on any OS, such as a JDK1.2 JVM on UNIX
// You can use Server.CreateObject() too (see below).
Demo = GetObject("java2:DemoClass")

// Invoke a method which performs a calculation
FVal = Demo.CalcFV(0.1, 12, -10, -19, 1)
Response.write("FVal = ".concat(FVal).concat("<BR>"))

// Invoke a method which returns another object.
aCollection = new Enumerator(Demo.getValues())
for (; !aCollection.atEnd(); aCollection.moveNext())
{
	Response.write("Value = ".concat(aCollection.item()).concat("<BR>"))
}

// Finally access a public field (which happens to be static)
Response.write("Demo.name = ".concat(Demo.name).concat("<BR>"))
Demo.name = "Alfred"
Response.write("Updated Demo.name = ".concat(Demo.name).concat("<BR>"))
%>
</BODY>
</HTML>

 

This is what you see when you access the ASP page

From the above you can see that the integration is extremely flexible -- J-Integra renders the Java object visible to ASP as though it were a COM object (in fact it is a COM object, because the J-Integra runtime loaded into the JVM, remote-enables any Java object, and talks DCOM directly to ASP).

The key question is of course how the string GetObject("java2:DemoClass") actually finds the appropriate JVM and returns a reference to the Java object as though it were a COM object. As you will see in the next section, it is a question of running one command from DOS on the ASP machine, and initializing the J-Integra runtime by calling one method in your JVM initialization code.

To try this out yourself

I assume that you are already very familiar with ASP, and that you have some Java knowledge (you know how to set up your CLASSPATH, and how to compile and run Java programs).

If you would like to try out these examples you'll need to download the J-Integra kit. An evaluation version is available for download from our web site: http://www.linar.com/.

On the ASP machine you will need a copy of the 'bin' directory from the kit. You do not need to install a JVM on the ASP machine (unless you are accessing local Java objects).

On the machine running your Java objects you will need a standard JVM (any one), and the J-Integra runtime, jintegra.jar from the J-Integra kit.

Configuring the ASP machine

First you'll need to create an ASP page with the above contents, and configure the Web Server such that the ASP page is available from your web browser. I assume you know how to do this (just cut-and-paste the text from your Browser).

If you are running ASP under Windows 2000 and the ASP virtual directory is set to be Pooled (the default), then open the Component Services management tool, go to COM+ Applications and change the properties for IIS Out-Of-Process Pooled Applications: set the Authentication Level to Connect in the Security pane (the default is Packet, which J-Integra does not currently support). If you'd prefer not to change this for all pooled apps, configure the virtual directory to be Isolated, and then change the specific entry for that Virtual directory that appears under COM+ Applications).

Next, start a DOS box, and run the J-Integra 'regjvmcmd' command which is in the J-Integra kit's 'bin' directory. You will need to know the TCP/IP name of the machine where the Java object which you will be accessing will be running -- where the JVM is.

If you will be running the JVM on the local machine, use 'localhost', otherwise specify the appropriate TCP/IP name.

This is the command:
regjvmcmd java2 jvm.host.name[3350]

That's it. All you need to do on the ASP machine is run that one command.

Configuring the machine running the JVM

First create a DemoClass.java file with the above contents (cut-and-paste from your browser), and compile it.

Java objects run inside a Java Virtual Machine. In order to access them from ASP they have to be run somewhere. You have two options. You can either have them run inside a JVM process that you already run, or you can start a new JVM process which will host them.

If you wish to do the latter, then create a small main program which registers the JVM, and then just hangs around. The DCOM requests from the ASP client are handled by J-Integra background threads. This is a suitable program:
public class DCOMBridgeJvm {
  public static void main(java.lang.String[] args) throws Exception {
    // com.linar.jintegra.Log.logImmediately(3, "jintegra.log");
    com.linar.jintegra.Jvm.register("java2", 3350);
    while(true) { // Otherwise JVM will exit.
      Thread.sleep(100000);
    }
  }
}
Note that there are no references to the Java classes being accessed. Any public Java class which has a public default constructor, which is in your CLASSPATH, can be accessed from ASP.

As you will no doubt have noticed, the parameters to Jvm.register() are the JVM name, and the port number used when registering the JVM. If you do not wish to hard-code the port number, you can just specify the JVM name, and set a java property instead (JINTEGRA_DCOM_PORT).

Just compile the DemoClass and the DCOMBridgeJvm, run it and access your page from ASP:

If you wish to have the Java objects run inside an existing JVM, then you will have to make sure that the J-Integra runtime (jintegra.jar, from the kit), and the classes you wish to access (in this case DemoClass) are in your CLASSPATH, and then add the Jvm.register(...) line to your Java startup code.

In the unlikely event that it doesn't work check that the JVM is registered correctly, using the regjvmcmd /list command on the ASP machine. Check the port number and machine name. If it still does not work, uncomment the Log.logImmediately(...) line above, and send us the generated log, and the file generated by doing checkconfig config.log on the ASP machine.

That's it

That's about it as far as accessing Java objects from ASP using J-Integra's DCOM mode. To summarize the key points: I'd strongly recommend you trying it out. It really is extremely straight-forward. Feel free to contact us with your suggestions and comments.

The next page shows how to load the JVM in-process. It relies on you having completed the above example first.


If you wish to use Server.CreateObject("some.progid") instead of GetObject("JvmName:ClassName"), you can use the J-Integra regprogid command on the ASP machine, to map a progid to a JvmName:ClassName combination, and then use Server.CreateObject().