Adobe ColdFusion 8

Examples: using Java with CFML

The following sections show several examples of using Java objects in CFML. They include examples of using a custom Java class, a standard Java API class in a user-defined function, a JavaBean, and an Enterprise JavaBean (EJB).

Using a Java API in a UDF

The following example of a user-defined function (UDF) is functionally identical to the GetHostAddress function from the NetLib library of UDFs from the Common Function Library Project, www.cflib.org. It uses the InetAddress class from the standard Java 2 java.net package to get the Internet address of a specified host:

<cfscript>
function GetHostAddress(host) {
    // Define the function local variables.
    var iaddrClass="";
    var address="";
    // Initialize the Java class.
    iaddrClass=CreateObject("java", "java.net.InetAddress");
    // Get the address object.
    address=iaddrClass.getByName(host);
    // Return the address
    return address.getHostAddress();
}
</cfscript>
<cfoutput>#gethostaddress("adobe.com")#</cfoutput> 

Using an EJB

ColdFusion can use EJBs that are served by JRun 4.0 servers. The JRun server jrun.jar file must have the same version as the jrun.jar file in ColdFusion.

To call an EJB, you use cfobject type="Java" to create and call the appropriate objects. Before you can use an EJB you must do the following:

  1. Have a properly deployed EJB running on a J2EE server. The bean must be registered with the JNDI server.
  2. Have the following information:
    • Name of the EJB server
    • Port number of the JNDI naming service on the EJB server
    • Name of the EJB, as registered with the naming service
  3. Install the EJB home and component interface compiled classes on your ColdFusion web server, either as class files in the web_root/WEB-INF/classes directory or packaged in a JAR file the web_root/WEB-INF/lib directory.

Note: To use an EJB served by a JRUN server, your ColdFusion installation and the JRun server that hosts the EJB must have the same version of the jrun.jar file (located in cf_root\runtime\lib directory in ColdFusion).

Although the specific steps for using an EJB depend on the EJB server and on the EJB itself, they generally correspond to the following order.

Use an EJB

  1. Use the cfobject tag to create an object of the JNDI naming context class (javax.naming.Context). You will use fields from this class to define the information that you use to locate the EJB. Because you only use fields, you do not initialize the object.
  2. Use the cfobject tag to create a java.util.Properties class object that will contain the context object properties.
  3. Call the init method to initialize the Properties object.
  4. Set the Properties object to contain the properties that are required to create an initial JNDI naming context. These include the INITIAL_CONTEXT_FACTORY and PROVIDER_URL properties. You might also need to provide SECURITY_PRINCIPAL and SECURITY_CREDENTIALS values required for secure access to the naming context. For more information on these properties, see the JNDI documentation.
  5. Use the cfobject tag to create the JNDI InitialContext (javax.naming. InitialContext) object.
  6. Call the init method for the InitialContext object with the Properties object values to initialize the object.
  7. Call the InitialContextext object's lookup method to get a reference to the home interface for the bean that you want. Specify the JNDI name of the bean as the lookup argument.
  8. Call the create method of the bean's home object to create a new instance of the bean. If you are using Entity beans, you typically use a finder method instead. A finder method locates one or more existing entity beans.
  9. Now you can use the bean's methods as required by your application.
  10. When finished, call the context object's close method to close the object.

The following code shows this process using a simple Java Entity bean on a JRun 4.0 server. It calls the bean's getMessage method to obtain a message.

<html>
<head>
    <title>cfobject Test</title>
</head>

<body>
<H1>cfobject Test</H1>
<!--- Create the Context object to get at the static fields. --->
<CFOBJECT 
    action=create 
    name=ctx 
    type="JAVA" 
    class="javax.naming.Context">

<!--- Create the Properties object and call an explicit constructor--->
<CFOBJECT 
    action=create 
    name=prop 
    type="JAVA" 
    class="java.util.Properties">

<!--- Call the init method (provided by cfobject)
        to invoke the Properties object constructor. --->
<cfset prop.init()>

<!--- Specify the properties These are required for a remote server only --->
<cfset prop.put(ctx.INITIAL_CONTEXT_FACTORY, "jrun.naming.JRunContextFactory")>
<cfset prop.put(ctx.PROVIDER_URL, "localhost:2908")>
<!--- <cfset prop.put(ctx.SECURITY_PRINCIPAL, "admin")>
        <cfset prop.put(ctx.SECURITY_CREDENTIALS, "admin")>
 --->
<!--- Create the InitialContext --->
<CFOBJECT 
    action=create 
    name=initContext 
    type="JAVA" 
    class="javax.naming.InitialContext">

<!--- Call the init method (provided through cfobject)
        to pass the properties to the InitialContext constructor. --->
<cfset initContext.init(prop)>

<!--- Get reference to home object. --->
<cfset home = initContext.lookup("SimpleBean")>

<!--- Create new instance of entity bean.
        (hard-wired account number). Alternatively,
        you would use a find method to locate an existing entity bean. --->
<cfset mySimple = home.create()>

<!--- Call a method in the entity bean. --->
<cfset myMessage = mySimple.getMessage()>

<cfoutput>
    #myMessage#<br>
</cfoutput>

<!--- Close the context. --->
<cfset initContext.close()>

</body>
</html>

Using a custom Java class

The following code provides a more complex custom class than in the example Creating and using a simple Java class. The Example class manipulates integer, float, array, Boolean, and Example object types.

The Example class

The following Java code defines the Example class. The Java class Example has one public integer member, mPublicInt. Its constructor initializes mPublicInt to 0 or an integer argument. The class has the following public methods:

Method

Description

ReverseString

Reverses the order of a string.

ReverseStringArray

Reverses the order of elements in an array of strings.

Add

Overloaded: Adds and returns two integers or floats or adds the mPublicInt members of two Example class objects and returns an Example class object.

SumArray

Returns the sum of the elements in an integer array.

SumObjArray

Adds the values of the mPublicInt members of an array of Example class objects and returns an Example class object.

ReverseArray

Reverses the order of an array of integers.

Flip

Switches a Boolean value.

public class Example {
    public int mPublicInt;

    public Example() {
        mPublicInt = 0;
    }

    public Example(int IntVal) {
        mPublicInt = IntVal;
    }

    public String ReverseString(String s) {
        StringBuffer buffer = new StringBuffer(s);
        return new String(buffer.reverse());
    }

    public String[] ReverseStringArray(String [] arr) {
        String[] ret = new String[arr.length];
        for (int i=0; i < arr.length; i++) {
            ret[arr.length-i-1]=arr[i];
        }
        return ret;
    }

    public int Add(int a, int b) {
        return (a+b);
    }

    public float Add(float a, float b) {
        return (a+b);
    }

    public Example Add(Example a, Example b) {
        return new Example(a.mPublicInt + b.mPublicInt);
    }

    static public int SumArray(int[] arr) {
        int sum=0;
        for (int i=0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }

    static public Example SumObjArray(Example[] arr) {
        Example sum= new Example();
        for (int i=0; i < arr.length; i++) {
            sum.mPublicInt += arr[i].mPublicInt;
        }
        return sum;
    }

    static public int[] ReverseArray(int[] arr) {
        int[] ret = new int[arr.length];
        for (int i=0; i < arr.length; i++) {
            ret[arr.length-i-1]=arr[i];
        }
        return ret;
    }

    static public boolean Flip(boolean val) {
        System.out.println("calling flipboolean");
        return val?false:true;
    }
}

The useExample ColdFusion page

The following useExample.cfm page uses the Example class to manipulate numbers, strings, Booleans, and Example objects. The CFML JavaCast function ensures that CFML variables convert into the appropriate Java data types.

<html>
<head>
    <title>CFOBJECT and Java Example</title>
</head>
<body>

<!--- Create a reference to an Example object --->
<cfobject action=create type=java class=Example name=obj>
<!--- Create the object and initialize its public member to 5 --->
<cfset x=obj.init(JavaCast("int",5))>

<!--- Create an array and populate it with string values,
        then use the Java object to reverse them. --->
<cfset myarray=ArrayNew(1)>
<cfset myarray[1]="First">
<cfset myarray[2]="Second">
<cfset myarray[3]="Third">
<cfset ra=obj.ReverseStringArray(myarray)>

<!--- Display the results --->
<cfoutput>
    <br>    
    original array element 1: #myarray[1]#<br>
    original array element 2: #myarray[2]#<br>
    original array element 3: #myarray[3]#<br>
    after reverseelement 1: #ra[1]#<br>
    after reverseelement 2: #ra[2]#<br>
    after reverseelement 3: #ra[3]#<br>
    <br>
</cfoutput>


<!--- Use the Java object to flip a Boolean value, reverse a string,
        add two integers, and add two float numbers --->
<cfset c=obj.Flip(true)>
<cfset StringVal=obj.ReverseString("This is a test")>
<cfset IntVal=obj.Add(JavaCast("int",20),JavaCast("int",30))>
<cfset FloatVal=obj.Add(JavaCast("float",2.56),JavaCast("float",3.51))>

<!--- Display the results --->
<cfoutput>
    <br>
    StringVal: #StringVal#<br>
    IntVal: #IntVal#<br>
    FloatVal: #FloatVal#<br>
    <br>
</cfoutput>

<!--- Create a two-element array, sum its values, 
        and reverse its elements --->
<cfset intarray=ArrayNew(1)>
<cfset intarray[1]=1>
<cfset intarray[2]=2>
<cfset IntVal=obj.sumarray(intarray)>
<cfset reversedarray=obj.ReverseArray(intarray)>

<!--- Display the results --->
<cfoutput>
    <br>
    IntVal1 :#IntVal#<br>
    array1: #reversedarray[1]#<br>
    array2: #reversedarray[2]#<br>
    <br>
</cfoutput><br>

<!--- Create a ColdFusion array containing two Example objects.
        Use the SumObjArray method to add the objects in the array
        Get the public member of the resulting object--->
<cfset oa=ArrayNew(1)>
<cfobject action=create type=java class=Example name=obj1>
<cfset VOID=obj1.init(JavaCast("int",5))>
<cfobject action=create type=java class=Example name=obj2>
<cfset VOID=obj2.init(JavaCast("int",10))>
<cfset oa[1] = obj1>
<cfset oa[2] = obj2>
<cfset result = obj.SumObjArray(oa)>
<cfset intval = result.mPublicInt>

<!--- Display the results --->
<cfoutput>
    <br>
    intval1: #intval#<br>
    <br>
</cfoutput><br>
</body>
</html>