Under most situations, when the method names are not ambiguous, ColdFusion can determine the data types that are required by a Java object, and often it can convert ColdFusion data to th
Trang 1Under most situations, when the method names are not ambiguous, ColdFusion can determine the data types that
are required by a Java object, and often it can convert ColdFusion data to the required types For example,
ColdFusion text strings are implicitly converted to the Java String type Similarly, if a Java object contains a doIt
method that expects a parameter of type int, and CFML is issuing a doIt call with a CFML variable x that contains
an integer value, ColdFusion converts the variable x to Java int type However, ambiguous situations can result from
Java method overloading, where a class has multiple implementations of the same method that differ only in their
parameter types
The following sections describe how ColdFusion handles the unambiguous situations, and how it provides you with
the tools to handle ambiguous ones
Default data type conversion
Whenever possible, ColdFusion automatically matches Java types to ColdFusion types
The following table lists how ColdFusion converts ColdFusion data values to Java data types when passing
arguments The left column represents the underlying ColdFusion representation of its data The right column
indicates the Java data types into which ColdFusion can automatically convert the data:
The following table lists how ColdFusion converts data returned by Java methods to ColdFusion data types:
Integer short, int, long (short and int might result in a loss of precision).
Real number float double (float might result in a loss of precision.
String, including lists String
short, int, long, float, double, java.util.Date, when a CFML string represents a number or date.
boolean, for strings with the value Yes, No, True, and False (case-insensitive).
Array java.util.Vector (ColdFusion Arrays are internally represented using an instance of a java.util.Vector
object.) ColdFusion can also map a CFML array to any of the following when the CFML array contains consistent data of a type that can be converted to the Java array’s data type: byte[], char[], boolean[], int[], long[], float[], double[], String[], or Object[] When a CFML array contains data of different of types, the conver- sion to a simple array type might fail.
Query object java.util.Map
XML document object Not supported.
ColdFusion component Not applicable.
boolean/Boolean Boolean
Trang 2ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
942
Resolving ambiguous data types with the JavaCast function
You can overload Java methods so a class can have several identically named methods At runtime, the JVM resolves
the specific method to use based on the parameters passed in the call and their types
In the section “The Employee class” on page 938, the Employee class has two implementations for the SetJobGrade
method One method takes a string variable, the other an integer If you write code such as the following, which
implementation to use is ambiguous:
<cfset emp.SetJobGrade(“1”)>
The “1” could be interpreted as a string or as a number, so there is no way to know which method implementation
to use When ColdFusion encounters such an ambiguity, it throws a user exception
The ColdFusion JavaCast function helps you resolve such issues by specifying the Java type of a variable, as in the
following line:
<cfset emp.SetJobGrade(JavaCast(“int”, “1”))>
The JavaCast function takes two parameters: a string representing the Java data type, and the variable whose type
you are setting You can specify the following Java data types: boolean, int, long, float, double, and String
For more information about the JavaCast function, see the CFML Reference.
Handling Java exceptions
You handle Java exceptions just as you handle standard ColdFusion exceptions, with the cftry and cfcatch tags
You specify the name of the exception class in the cfcatch tag that handles the exception For example, if a Java
object throws an exception named myException, you specify myException in the cfcatch tag
Note: To catch any exception generated by a Java object, specify java.lang.Exception for the cfcatch type attribute To
catch any Throwable errors, specify java.lang.Throwable in the cfcatch tag type attribute.
The following sections show an example of throwing and handling a Java exception
Trang 3For more information on exception handling in ColdFusion, see “Handling Errors” on page 246.
Example: exception-throwing class
The following Java code defines the testException class that throws a sample exception It also defines a myException
class that extends the Java built-in Exception class and includes a method for getting an error message
The myException class has the following code It throws an exception with a message that is passed to it, or if no
argument is passed, it throws a canned exception
public void doException() throws myException {
throw new myException("Throwing an exception from testException class");
}
}
Example: CFML Java exception handling code
The following CFML code calls the testException class doException method The cfcatch block handles the
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) {
Trang 4ColdFusion 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
corre-spond 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
Trang 59 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
<! - 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")>
<! - 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()>
Trang 6Using a custom Java class
The following code provides a more complex custom class than in the example “Creating and using a simple Java
class” on page 938 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:
public class Example {
public int mPublicInt;
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;
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.
Trang 7public int Add(int a, int b) {
public Example Add(Example a, Example b) {
return new Example(a.mPublicInt + b.mPublicInt);
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++) {
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
<! - 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)>
Trang 8original 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 ->
<! - Create a two-element array, sum its values,
and reverse its elements ->
<! - 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[1] = obj1>
<cfset oa[2] = obj2>
Trang 9<cfset intval = result.mPublicInt>
<! - Display the results ->
Trang 10Chapter 50: Using Microsoft NET
Assemblies
You can use ColdFusion to call local or remote Microsoft NET assembly class methods and access assembly fields
This topic describes how to configure and run the ColdFusion NET extension software and how to access and use
.NET classes in your ColdFusion code For information about NET technology or how to develop NET
applica-tions, see Microsoft NET documentation
Contents
About ColdFusion and NET 950
Accessing NET assemblies 953
Using NET classes 957
.NET Interoperability Limitations 965
Example: Using a custom class to access Microsoft Word 966
Advanced tools 968
About ColdFusion and NET
ColdFusion lets you access and use Microsoft NET assembly classes as CFML objects CFML applications can use
.NET assemblies in the following ways:
• Directly access and control Microsoft products, such as Word, Excel, or PowerPoint
• Use existing NET components
• Use NET assemblies that you create to leverage features that are difficult to use or not available in ColdFusion
or Java (Because ColdFusion is a J2EE application, if you cannot code a feature in CFML, it is more efficient to create
it in Java than to use NET.)
The NET classes that your application uses do not have to be local; your ColdFusion application can access NET
components that are located on remote systems, even systems that are located outside your firewall Also, the
ColdFusion system does not require NET run-time software installed to use remote NET components, so
ColdFusion running on a UNIX, Linux, Solaris, or OS-X system can access and use NET assemblies
You can use the cfobject tag or CreateObject function to create a reference to a NET class object, by specifying
either .NET or dotnet as the object type You use the reference to access the NET class fields and call the NET class
methods This technique provides a tightly coupled, stateful, efficient method for accessing NET classes from
ColdFusion As an alternative, your NET application can make the class methods available as web services; however,
using a web service is less reliable, has lower performance, and is less scalable than using ColdFusion objects for the
.NET classes
Note: NET applications cannot access ColdFusion component functions directly You can make the functions available
as web services by specifying remote access For more information on creating ColdFusion web services, see “Using Web
Services” on page 900.
Trang 11Because you use the NET assembly classes the same way that you use any other ColdFusion object, you do not have
to understand the details of NET technology; you only have to understand how to use the specific NET class that
you are accessing Code that uses a NET method can be as simple as the following lines:
<cfobject type = ".NET" name = "mathInstance" class = "mathClass"
assembly = "C:/Net/Assemblies/math.dll">
<cfset myVar = mathInstance.multiply(1,2)>
ColdFusion NET access has the following additional features:
• If you make a change in the NET assembly, ColdFusion automatically recognizes the change and uses that
version for the next invocation
• Your application can access NET assemblies running on multiple machines
• You can secure the communication between ColdFusion and NET by using SSL
• Primitive data types are automatically mapped between ColdFusion and NET data types
How NET access works
For ColdFusion to access NET assemblies, ColdFusion NET extension software must run on the system that hosts
the assemblies A ColdFusion system that accesses only remote assemblies does not require the NET extension The
.NET extension software provides the NET-side connectivity features that enable access to NET assemblies,
including a NET-side agent (which normally runs as the ColdFusion 8 NET service) that listens for and handles
requests from the ColdFusion system
On the ColdFusion system, the ColdFusion objects use Java proxies that act as local representatives of the NET
classes These proxies use binary TCP or SOAP-based HTTP communication to access a NET-side agent The agent
then uses a DLL to invoke the NET assembly classes This communication is required in all cases, even if ColdFusion
and the NET assemblies are on the same system
The following image shows how CFML-to-.NET access works:
Trang 12ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
952
If your NET assemblies are on the local system, ColdFusion automatically creates and manages all required proxies
and configuration information You must ensure only that the NET extension is installed on your system and that
the ColdFusion 8 NET Service is running; you can use the cfobject tag or CreateObject function to access the
assemblies without any additional steps
If the assemblies are on a remote system, you install and use the ColdFusion 8 NET extension software on the NET
system to create Java proxies for the NET classes, and then move or copy them to the ColdFusion system You must
also edit the JNBDotNetSide.exe.config file on the remote system to specify the NET classes you use The NET
system requires the following NET extension software:
• JNBDotNetSide.exe, the NET-side agent that communicates with the ColdFusion system (normally run as the
ColdFusion 8 NET service)
• JNBDotNetSide.exe.config, a configuration file that identifies the NET assemblies that can be accessed by
ColdFusion
• jnbproxy.exe and jnbproxyGui.exe, command-line and GUI-based programs that generate the Java proxies that
represent the NET assemblies
• Additional support files, including JNBShare.dll, which invoke the NET assembly classes
For information on installing the ColdFusion NET extension, see Installing and Using ColdFusion.
Note: When you install a new NET version, you must reinstall the ColdFusion NET extension.
TCP/Binary or HTTP/SOAP communications
JNBDotNetSide.exe
(runs as a Windows service)
JNBShare.dll
Uses
Invokes NET Assembly
Trang 13Accessing NET assemblies
ColdFusion provides two methods for accessing NET assemblies:
• A local access method for NET objects that are installed on the ColdFusion system
• A remote access method for NET objects located on other systems
For both methods, you must install the ColdFusion NET extension and run the ColdFusion 8 NET service on the
system that hosts the assemblies You do not need to install the extension or run the service on a ColdFusion system
that accesses only remote assemblies For information on installing the ColdFusion NET extension, see Installing
and Using ColdFusion.
Accessing local assemblies
For local access, ColdFusion automatically generates and uses proxies for the required NET assemblies when you
first use the cfobject tag or CreateObject function ColdFusion caches the proxies for future use, so it does not
generate assembly proxies each time
Usually when you are accessing local NET assemblies, you do not have to override the default communication
configuration settings Sometimes you might have to specify these settings, however If other software on your
system uses the default 6086 port, for example, you must change the port number specification in the
jnbridge\DotNetSide.exe.config file, and you must specify the changed port number in your cfobject tag or
CreateObject tag For information on changing the port number specification, see “Configuring the NET-side
system” on page 956,
To use the local access method, you need only to use the cfobject tag or CreateObject function to create and
access the proxy You can use the resulting ColdFusion object to construct the NET object, call the NET object’s
methods, and access its fields For detailed information on using NET classes, see “Using NET classes” on page 957
Accessing remote assemblies
The remote access technique accesses NET assemblies by using TCP or HTTP to communicate with a NET-side
agent on a remote system You create proxy instances and call assembly methods as you do in the Local access
method, but you must first configure the remote NET-side agent and, in most cases, the proxy classes that represent
the remote NET classes
Configure remote NET access
1 On the remote system, install the ColdFusion 8 NET integration software and run the NET-side agent (see
Installing and Using ColdFusion).
2 If the NET assemblies reside only on the remote system, generate proxy JAR files on that system that represent
the assemblies (see “Generating the Java proxy classes” on page 954) Then copy or move the proxy files to the local
system If identical NET assemblies also reside on the local system, you can skip this step
3 Configure the NET-side system for remote access (see “Configuring the NET-side system” on page 956)
Trang 14ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
954
Generating the Java proxy classes
The Java proxy generation code requires direct access to the NET assemblies to generate the proxy classes
Therefore, if the system that runs your ColdFusion application does not have the assemblies installed, you must run
a tool on the NET-side system to create the Java proxies ColdFusion installs two proxy generation programs,
jnbproxyGui.exe and jnbproxy.exe in the jnbridge directory when you install the NET services The
jnbproxyGui.exe program is a Windows UI application, and the jnbproxy.exe program is a command line
appli-cation Both programs have identical capabilities
Note: If the system running the ColdFusion application has the assemblies installed, but must access remote versions of
the assemblies (for example, because of configuration differences), you do not need to manually generate the proxy
classes, and you can skip this step Instead, specify the paths to the local exe or dll files in the assembly attribute of the
cfobject tag (or CreateObject function) and specify the remote server in the server attribute You must configure
the remote system for access, however.
On a ColdFusion system, the jnbproxyGui and jnbproxy programs are located in the cfroot\jnbridge directory When
you use the stand-alone installer, the programs are located in the installDir\jnbridge directory.
This topic provides the basic information necessary to generate a proxy JAR file using the jnbproxyGui tool
Additional information is available in the following locations:
• The jnbridge directory includes a jnbproxy.chm Windows Help file with more complete documentation on the
JNBridge technology that powers the ColdFusion NET feature, including detailed information on both the
jnbproxyGui and jnbproxy programs
• The jnbridge\docs subdirectory includes additional documentation, including users guide.pdf, a PDF version of
the information in the Help file
Note: The JNBridge documentation includes information on features that are not supported in ColdFusion ColdFusion,
for example, does not support access from NET assemblies to ColdFusion or memory-only communication.
Using the jnbproxyGui tool
You use the jnbproxyGui program to generate a proxy JAR file
Generate and install a proxy JAR
1 Start JNBProxyGui.exe
2 The first time you run the program, it displays the Enter Java Options dialog box Configure the options, and
click OK
You can change the configuration settings at a later time by selecting Project > Java Options
On a system with ColdFusion: If ColdFusion is currently running on this system, ensure that the Start Java
Automatically option, located on the right side of the JNBProxy Enter Java Options (Project > Java Options)
dialog box is cleared Leave the default values for the other settings
When you open an existing project, you might get a Restart Java Side pop-up warning with the message "You
must stop and restart the Java side before these changes to the classpath can take effect." You can ignore this
message and click OK to proceed
When you start the program, the Java Options dialog box might appear You do not have to make any changes;
click OK or Cancel to open the Launch JNBProxy dialog box
In some cases, JNBProxyGui might behave as follows when the Start Java Automatically option is not selected
On a system without ColdFusion: If ColdFusion is not currently running on the system, ensure the following
options, which are located on the right side of the interface, are set Leave the default values for the other settings
Trang 15• Ensure that the Start Java Automatically option is selected.
• Specify the java.exe file to use to compile the JAR file You can use a Java 1.4 or 1.5 (J2SE 5.0) version of this
file
• Specify the jnbcore.jar file The ColdFusion server installer puts this file in the cfroot\lib directory The J2EE
installer puts the file in the cf_webapp_root\WEB-INF\cfusion\lib directory.
• Specify the bcel.jar file The ColdFusion server installer puts this file in the cfroot\lib directory The J2EE
installer puts the file in the cf_webapp_root\WEB-INF\cfusion\lib directory.
3 In the Launch JNBProxy dialog box, select Create New Java > NET Project, and click OK
4 In the main Java proxy generation interface, set up and build a project:
a If you have not already done so, you must add the directory that contains your assemblies to the JNBProxy
your project Select Project >Edit Assembly List In the Assembly List dialog box, click the Add button In the
New Assembly List Element dialog box, navigate to the directory that contains your assemblies Select the
directory (or directories) in the tree, and click OK Then click OK in the Edit Assembly List dialog box
b Open the Locate Assembly File dialog box (Project > Add Classes From Assembly File) and navigate to the
directory that you added to the assembly list in step a Select the assembly file or files that contain classes that
require proxies and click OK
c The classes in the selected file, and other NET core classes on which they depend, appear in the
Environment pane Select all classes for which you want proxies in your JAR file, and click the Add+ button to
add the selected classes and all supporting classes
d In the Exposed Proxies list, select the classes to include in the JAR file Normally, you should select all the
listed classes, which ensures that all required classes are included
e Select Project > Build from the main menu In the Save Generated Proxies dialog box, specify the location
and JAR file in which to save the generated proxies, and click Save
f After the project is built, select File > Save Project and specify the file in which to save your project
The next time you run the jnbproxyGui program, you can select your project and reuse your previous
settings, including the Assembly List
5 Copy the JAR file to a directory on your ColdFusion system You specify this path in the cfobject tag assembly
attribute
Supporting classes
JNBProxy can generate proxies not only for the NET classes that are explicitly listed, but also for supporting classes
A supporting class for a given NET class is any class that might be needed as a direct or indirect result of using that
.NET class For a given NET class, supporting classes include all of the following:
• The class
• The class’s superclass or superinterface (if it exists) and all of its supporting classes
• The class’s implemented interfaces (if any) and all of their supporting classes
• For each field in the class:
• The field’s class and all of its supporting classes
• For each of the field’s index parameters, the parameter’s class and all of its supporting classes
• For each method in the class:
• The method’s return value’s class (if any) and all of its supporting classes
Trang 16ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
956
• For each of the method’s parameters, the parameter’s class and all of its supporting classes
• For each constructor in the class, for each of the constructor’s parameters, the parameter’s class and all of its
supporting classes
Unlike Java, where supporting classes include exceptions declared to be thrown by methods, NET supporting classes
don’t include thrown exceptions, because they are not declared in advance
The number of supporting classes depends on the classes explicitly listed, but there are often 200-250 classes Usually
you generate all supporting classes However, there are situations where, to save time or space, you can generate only
those classes explicitly specified, without supporting classes
If a proxy for a supporting class has not been generated, and a proxy for such a class is later needed when the proxies
are used, the proxy for the nearest superclass to the required class is used instead If that proxy hasn’t been generated,
the proxy for that superclass’s superclass will be used if it has been generated, and so forth, until the proxy for
System.Object (which is always generated) is encountered Thus, even with an incomplete set of proxies, code will
execute, although functionality and other information may be lost
In the jnbproxyGui tool, when you click the Add button, the list includes only the explicitly listed classes When you
click the Add+ button the list also includes the supporting classes In the jnbproxy command line program, the
default command generates proxies for the supporting classes; use the /ns option to override this default
Configuring the NET-side system
To configure the NET-side system, you edit the jnbridge\JNBDotNetSide.exe.config configuration file in the
following ways:
• For local assemblies, you must edit this file only if you do not use the default port, or if you use SSL security
• For a NET assembly on a remote machine, you must register the assemblies in this file to make it accessible to
ColdFusion
Edit the configuration file
1 Ensure the following lines are in the <configSections> subsection of the <configuration> section:
<jnbridge>
<javaToDotNetConfig scheme="Protocol" port="local port number"
useSSL="true|false" certificateLocation="server certificate path"/>
</jnbridge>
• The scheme attribute specifies the communications protocol, and must be jtcp or http
• The port number is the port of the NET-side agent, normally 6086
• The useSSL attribute specifies whether to use SSL for secure communications The attribute is optional; the
default is to not use SSL
• The certificateLocation attribute specifies the location of the server SSL certificate It is required only
if the useSSL attribute is true
These settings must be the same as the corresponding attributes in your cfobject tag
2 If the NET assemblies are on a remote system, specify the assemblies that ColdFusion will access by adding the
following elements inside the <jnbridge> section
<assemblyList>
<assembly file=”path to assembly or fully qualified name”/>
Trang 17
3 Stop and restart the NET-side agent, if it is running For example, on a ColdFusion system, restart the
ColdFusion 8 8 NET Service Your ColdFusion application can now access the NET classes that you configured
The following example is a bare-bones JNBDotNetSide.exe.config file that specifies a NET-side TCP server
config-uration The server communicates by using TCP binary mode and listens on port 6086 Java clients can access classes
from the C:\F\x.dll assembly and from System.Windows.Forms, which is in the GAC:
Using NET classes
You use NET assembly classes the same way you use Java and other objects that you create using the cfobject tag
or CreateObject function In the simplest case, your application code only has to use the following format to
include a local NET class method:
<cfobject type = ".NET" name = "mathInstance" class = "mathClass"
assembly = "C:/Net/Assemblies/math.dll">
<cfset myVar = mathInstance.multiply(1,2)>
Using CFScript and the CreateObject function, you can do the following:
Note: You cannot load two DLLs with same fully qualified name ColdFusion always uses the first DLL that it accesses
until the server is restarted For example, if page1.cfm uses c:\dev\a.dll and page2.cfm uses c:\dev2\a.dll, and both DLLs
have the same fully qualified name, the first DLL file to be loaded remains loaded, and both CFML pages use it.
When you create objects and access class methods and fields, and convert data types between ColdFusion and NET,
you must be aware of the considerations and limitations described in the following sections:
Trang 18• Limitations described in the “Limitations” section of cfobject: NET object in the CFML Reference.
Instantiating objects and calling class constructors
When you use the cfobject tag to create a NET object, ColdFusion does not create an instance of the object
ColdFusion creates the object instance in either of the following cases:
• If the class has a default constructor, ColdFusion automatically calls the constructor when you first invoke a
non-static method of the object
• If the class does not have a default constructor, or if the class has multiple constructors and you do not want to
use the default, call the special init method of the ColdFusion object The cfobject tagautomatically creates init
methods for all class constructors Using the init method causes ColdFusion to call the class constructor with the
corresponding number and types of parameters For example, the following tags cause ColdFusion to call the
MyClass constructor that takes two integer parameters:
<cfobject type=".NET" name="myObj" class="com.myCo.MyClass"
assembly="c:\assemblies\myLib.dll">
<cfset myObj.init(10, 5)>
Note: ColdFusion does not create instances of objects if you use only their static methods.
Calling methods
You call NET methods in the same way that you use any other ColdFusion object methods For example, if the
MyClass class has a getName method that takes a numeric ID and returns a name, you would call the method as
follows:
<cfset theID="2343">
<cfset userName=mObj.getName(theID)>
Getting and setting fields
You can access and change public fields of any NET class by calling the following methods:
Get_fieldName()
Set_fieldName(value)
For example, if the NET class has a public field named accountID, you can access and change its value by using the
Get_accountID() and Set_accountID() methods, as follows:
<cfobject type=".NET" class="com.myCo.MyClass"
assembly="c:\assemblies\myLib.dll" name="myObj">
<cfset theAccount=myObj.Get_accountID()>
<cfset myObj.Set_accountID(theAccount + 1)>
You can access, but not modify final fields, so you can only call Get_fieldName() for these fields
Converting between NET and ColdFusion data types
Accessing NET classes requires a Java proxy on the ColdFusion system and NET code on the target system, so data
must be converted among ColdFusion, Java, and NET (to be exact, Microsoft Intermediate Language, or MSIL) data
types ColdFusion converts data types automatically Usually, you do not have to take any special steps to ensure
correct conversion There are some conversion limitations, and in some cases you must explicitly specify a data type
when you call a method in a NET proxy object
Trang 19The following paragraphs describe some the data conversion issues and how to handle them For a detailed
specifi-cation of how ColdFusion converts among ColdFusion data, Java data types, and NET data types, see cfobject:
.NET object in the CFML Reference.
Data type conversion rules and techniques
ColdFusion converts data automatically among ColdFusion, Java, and CLR data types The following table indicates
how ColdFusion converts among NET Common Language Runtime (CLR) primitive and standard data types, the
Java data types used in the proxies to represent CLR data types, and ColdFusion data types in your CFML
appli-cation
.NET type Java type ColdFusion type
The returned number retains greater precision than is normally displayed in ColdFusion Use the PrecisionEvaluate function to access and display the full precision of a returned double value You can also pass a value with full double precision to a NET method.
enum Not converted, but enumerator elements can be accessed directly by using the format
Enumerator_variable.enumerator, as in MyColor.Red
System.Collec-tions.ArrayList
java.util.ArrayList Array
Note: ColdFusion converts from NET type to ColdFusion type only, it does not convert
ColdFu-sion Arrays to NET ArrayLists.
System.Collec-tions.Hashtable
table
java.util.Hash-Structure
Note: ColdFusion converts from NET type to ColdFusion type only, it does not convert
ColdFu-sion Structures to NET Hashtables System.Data.DataT-
able
Query
Note: ColdFusion converts from NET type to ColdFusion type only, it does not convert
ColdFu-sion Queries to NET DataTables
Trang 20ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
960
Using decimal numbers
You must use the JavaCast function to convert ColdFusion data into BigDecimal format before you pass the value
to a NET function, as in the following example:
<cfset netObj.netFunc(javacast("bigdecimal","439732984732048"))>
ColdFusion automatically converts returned decimal and System.Decimal values to ColdFusion string
representa-tions
Ensuring decimal and date/time conversions
ColdFusion converts NET decimal or System.Decimal types only if the proxy for System.Decimal is a value type
proxy Similarly, it converts NET System.DateTime values to ColdFusion Date-time values only if the proxy for
System.DateTime is a value type proxy The ColdFusion server always uses value proxies when it generates these
proxies If you use the JNBProxyGUI.exe tool to generate the proxy, however, you must make sure to generate the
proxy for System.Decimal as value type
Converting data to System.Object type
When a NET method specifies System.Object (as opposed to a specific Object subclass, such as System.Boolean)
as the argument type, and you want to pass primitive values as arguments to that method, you must use the
javacast function to identify the data conversion Once ColdFusion knows the data type, it automatically converts
to the appropriate NET type Here is the table that describes the conversion rule from ColdFusion type to NET type
System.DateTime java.util.Date Date/time
decimal
System.Decimal
java.math.BigDe cimal
String representation of the decimal number.
For details on using decimal numbers, see “Using decimal numbers” on page 960 System.Object If a NET argument is of type System.Object, ColdFusion Strings are converted directly Other
types require using the JavaCast function.
ColdFusion cannot convert System.object instances returned by NET methods to ColdFusion types, but you can access them using the Object methods.
For detailed information, see “Converting data to System.Object type” on page 960
bool / System.Boolean boolean
bool[] / System.Boolean[] boolean[]
char[] / System.Char[] char[]
double / System.Double double
double[] / System.Double[] double[]
float / System.Single float
float[] / System.Single[] float[]
int[] / System.Int32[] int[]
.NET type Java type ColdFusion type
Trang 21Note: You do not need to use a JavaCast function to convert ColdFusion string variables They are automatically be
converted to NET System.String.
You must create special objects for NET primitive unsigned data types, such as byte (unsigned byte), ushort
(unsigned short), uint (unsigned int) and ulong (unsigned long), for which there are no corresponding java types
The following table lists the NET primitive types and the corresponding class you must use
You must use the createObject function or cfobject tag to create these special objects, in the same manner as you
create other NET classes, before you use them in your assignment statement For example, the following line creates
a ushort representation of the value 100:
<cfset boxedUShort = createObject(".NET" "System.BoxedUShort").init(100)>
The following example creates a System.Hashtable object and populates it with examples of all types of primitives
<! - create a NET Hashtable ->
<cfset table = createObject(".NET", "System.Collections.Hashtable")>
<! - call HashTable.add(Object, Object) method for all primitives ->
<cfset table.add("shortVar", javacast("short", 10))>
<cfset table.add("sbyteVar", javacast("byte", 20))>
<cfset table.add("intVar", javacast("int", 123))>
<cfset table.add("longVar", javacast("long", 1234))>
<cfset table.add("floatVar", javacast("float", 123.4))>
<cfset table.add("doubleVar", javacast("double", 123.4))>
<cfset table.add("charVar", javacast("char", 'c'))>
<cfset table.add("booleanVar", javacast("boolean", "yes"))>
<cfset table.add("StringVar", "Hello World")>
<cfset table.add("decimalVar", javacast("bigdecimal", 123234234.505))>
<! - call HashTable.add(Object, Object) for unsigned primitive types ->
<cfset boxedByte = createObject(".NET", "System.BoxedByte").init(10)>
<cfset table.add("byteVar", boxedByte)>
<cfset boxedUShort = createObject(".NET", "System.BoxedUShort").init(100)>
<cfset table.add("ushortVar", boxedUShort)>
<cfset boxedUInt = createObject(".NET", "System.BoxedUInt").init(123)>
<cfset table.add("uintVar", boxedUInt)>
<cfset boxedULong = createObject(".NET", "System.BoxedULong").init(123123)>
sbyte []/ System.Sbyte[] byte []
short[] / System.Int16[] short[]
.NET type Class used in cfobject/createObject
byte / System.Byte System.BoxedByte
ushort / System.UInt16 System.BoxedUShort
uint / System.UInt32 System.BoxedUInt
ulong / System.UInt64 System.BoxedULong
Trang 22ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
962
<cfdump var="#DotNetToCFType(table)#">
Any other NET objects can be passed as it is
Handling ambiguous type conversions
ColdFusion cannot determine the correct data type conversion if a method has multiple signatures with the same
number of parameters that differ only in the parameter data types In this case, use the JavaCast method to convert
the ColdFusion data to the Java type that corresponds to the NET type
For example, if a NET class has methods myFunc(ulong) and myFunc(int), use the JavaCast method to convert
your ColdFusion variable to the Java float or int data type, as the following line shows:
myFunc(JavaCast(int, MyVar));
Similarly, if a NET class has methods myFunc(int) and myFunc(String), use the JavaCast method to convert your
ColdFusion variable to the Java int or String data type, as shown in the following line:
myFunc(JavaCast(String, "123");
In some cases, the JavaCast function cannot eliminate ambiguity because a single Java type corresponds to multiple
.NET types In these cases, ColdFusion creates a proxy with only one method, which uses the NET data type that
corresponds directly to a Java type
For example, if the NET class has methods myFunc(ulong) and myFunc(float), the generated proxy has only one
method This method calls myFunc(float), because the Java float type used to handle ColdFusion floating point
numbers corresponds directly to the NET float type In this case, you can never call the NET myFunc(ulong)
method
Working with complex NET data types
When you use complex NET data such as Hashtable, ArrayList and DataTable, ColdFusion normally automatically
converts the data to the corresponding ColdFusion datatype: structure, array and query, respectively When you
work with this data you take specific actions to enable the proper access and conversion of the data, as follows:
• You must use associative array notation to properly access NET Hashtable data from ColdFusion
• You cannot use ColdFusion variables directly in parameters that take Hashtable, ArrayList or DataTable input
• You can disable automatic conversion of complex NET data to ColdFusion types
• You can manually convert complex NET data to ColdFusion types
Using Hashtable data in ColdFusion
.NET Hashtables are case sensitive, but most methods of ColdFusion structure access are case insensitive Only
associative array notation of the form structName["keyName"] is case sensitive When NET Hashtables are
converted to CF structure, the entire data set is converted, even if the element keys differ only in case Therefore, to
get the values of the keys that differ only in case, you must use associative array notation
The following example shows this issue It creates a Hashtable object with three entries whose key values vary only
in case In the example, output using dot-delimited structure notation always returns the same value, corresponding
to the all-uppercase key, but associative array notation returns the correct result
<! - Create a Hashtable and convert it to a ColdFusion structure ->
<cfset table = createObject(".NET", "System.Collections.Hashtable")>
<cfset table.add("Key", "Value1")>
<cfset table.add("KEY", "Value2")>
Trang 23<cfset cftable = DotNetToCFType(table)>
Using Net ArrayList in ColdFusion
ColdFusion converts System.Collections.ArrayList objects to ColdFusion arrays, and you can perform all standard
ColdFusion array operations on them The following example shows this usage:
.Net Code:
public ArrayList getList(){
ArrayList myAL = new ArrayList();
<cfset cflist = netObject.getList()>
<cfloop array="#cflist#" index="item">
Using ADO.Net DataTable in ColdFusion
ColdFusion converts System.Data.DataTable objects to ColdFusion query objects, and you can perform all standard
ColdFusion query operations on them The following example shows this usage:
SqlDataReader reader = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
return dt;
Trang 24Using ColdFusion complex types in NET input parameters
When a NET method returns an ArrayList, Hashtable or DataTable, ColdFusion automatically converts it to a
ColdFusion array, structure or query, respectively However ColdFusion does not automatically convert from
ColdFusion data types to these NET types (ColdFusion does automatically convert ColdFusion arrays to Net array
types.) Therefore, you cannot use ColdFusion variables directly as input parameters to NET object instance methods
that require NET System.Collection.ArrayList, System.Collection.Hashtable, or System.Data.DataTable types
Instead you must create instances of these NET types and populate them with the required data before you pass
them to the NET method For an example of creating and populating a System.Collection.Hashtable object, see the
example at the end of the “Converting data to System.Object type” section
Disabling automatic conversion of complex NET data
You can disable automatic conversion of NET System.Collections.Hashtable,
System.Collections.ArrayList or System.Data.DataTable objects to the corresponding ColdFusion
structure, array or query objects You might want to do this under the following circumstances:
• If a collection or DataTable returned by a NET method is very large and you only want a small subset of the data
If auto conversion is enabled, ColdFusion creates a data structure with all the object’s fields This might take
signif-icant time and resources, because ColdFusion must invoke NET methods internally to get each of the fields You can
disable the automatic conversion and retrieve the fields or data from NET objects like any other objects
• If you invoke a NET method that returns a complex variable, and then pass the variable to another NET method
as argument If automatic conversion is enabled, you cannot pass the Hashtable object from the first method directly
to the second method
To disable automatic conversion, set the JVM coldfusion.dotnet.disableautoconversion system property to true For
example, in a ColdFusion stand-alone server, or if you use JRun as your J2EE server, include the following setting in
the JVM.config file:
-Dcoldfusion.dotnet.disableautoconversion=true
Manually converting complex NET objects
Use the DotNetToCFTypefunction to convert a System.Collections.Hashtable,
System.Collections.ArrayList or System.Data.DataTable object to a ColdFusion structure, array or query
respectively when either of the following circumstances are true:
• You have set the coldfusion.dotnet.disableautoconversion system property to true
• Automatic conversion is enabled, you created the complex NET object by using the createObject function or
cfobject tag, and you want to convert this object into the corresponding ColdFusion representation
For an example of using the function, see DotNetToCFType in the CFML Reference.
Using NET objects
.NET fields and return values with class types are available in ColdFusion as NET objects You can use the object’s
methods to access object data and make it available to ColdFusion using supported data types
Trang 25The following example gets information about a system’s drives It calls the System.IO.DriveInfo.GetDrives() method
to get an array of System.IO.DriveInfo objects, one per drive It then calls the object methods to get specific
infor-mation about the drives, and displays the inforinfor-mation The example uses a cfdump tag to simplify the code
Note: The System.IO.DriveInfo is not included in the NET 1.x framework It is included in NET 2.0 and later
frame-works For information on determining the NET framework, see “Determining and changing the NET version” on
page 971.
<! - Create a query for the drive information results ->
<cfset result=QueryNew("name,type,isready,format,label,totalsize,freespace"
,"varchar,varchar,bit,varchar,varchar,double,double")>
<! - Create a NET System.IO.DriveInfo object ->
<cfobject type=".NET" name="sidiClass" class="System.IO.DriveInfo">
<! - Get the drives ->
<cfset drives=sidiClass.GetDrives()>
<! - Loop through drives ->
<cfloop from="1" to="#ArrayLen(drives)#" index="i">
<! - Add a row to the query. ->
<cfset QueryAddRow(result)>
<! - Get the drive name, type, and ready flag ->
<cfset QuerySetCell(result, "name", drives[i].Get_Name())>
<cfset QuerySetCell(result, "type",
drives[i].Get_DriveType().ToString())>
<cfset QuerySetCell(result, "isready", drives[i].Get_IsReady())>
<! - Get extra details ONLY if the drive is ready ->
<cfif drives[i].Get_IsReady()>
<cfset QuerySetCell(result, "format", drives[i].Get_DriveFormat())>
<cfset QuerySetCell(result, "label", drives[i].Get_VolumeLabel())>
<cfset QuerySetCell(result, "totalsize", drives[i].Get_TotalSize())>
<cfset QuerySetCell(result, "freespace",
drives[i].Get_AvailableFreeSpace())>
</cfif>
</cfloop>
<cfdump var="#result#">
.NET Interoperability Limitations
ColdFusion NET interoperability has the following limitations
• You cannot invoke methods with pointers as arguments or the return type
• You cannot invoke methods that take Out parameters
• ColdFusion can only convert from System.Data.DataTable, System.Collection.Hashtable and
System.Collection.ArrayList to ColdFusion data types ColdFusion cannot convert from ColdFusion queries,
struc-tures, and arrays to these System data types; however, it can convert from ColdFusion arrays to the CLR array type
Therefore, you cannot pass structures or queries directly to NET methods
• You cannot access NET UI components
• You cannot use callbacks (events and Delegates) from NET side
• ColdFusion cannot determine the correct data type conversion if a method has multiple signatures that have the
same number of parameters and differ only in the parameter data types In this case, use the JavaCast method to
convert the ColdFusion data to the Java type that corresponds to the NET type
Trang 26ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
966
• If the JavaCast function cannot eliminate ambiguity between functions with the same number of parameters
because a single Java type corresponds to multiple NET types, ColdFusion creates a single proxy that uses the NET
data type that corresponds directly to a Java type
For more information on how to ambiguous handle type conversions, see “Converting between NET and
ColdFusion data types” on page 958
• Assemblies registered in the DotNetSide.exe.config file must have unique class names If two or more assemblies
have the same class name, method invocation can result in an error or can give the wrong result For example, you
should not have two DLLs, a.dll and b.dll, that contain the same class name, nam1.name2.MyClass If you use one
dll and later want to use another dll that contains a class that clashes with first, you must restart the ColdFusion NET
Service if ColdFusion and NET both are on the same machine If they are on the different machines, you must
remove the first DLL's entry from the DotNetSide.exe.config file and restart the ColdFusion NET Service on the
Windows machine hosting the NET service
Example applications
The first application example uses a Microsoft NET system class method directly The second application example
uses a custom C# class to access Microsoft Word
Example: Using a NET class directly
The following example uses the Microsoft NET System.Net.NetworkInformation.Ping class method directly to ping
servers This class is supported in NET version 2.0 and later
<! - This function pings the specified host ->
<cffunction name="Ping" returntype="string" output="false">
<cfargument name="host" type="string" required="yes">
<! - Local vars ->
<cfset var pingClass="">
<cfset var pingReply="">
<! - Get Ping class ->
<cfobject type=".NET" name="pingClass"
Example: Using a custom class to access Microsoft Word
The following ColdFusion application uses a custom C# WordCreator class, and supporting classes in Microsoft
Office and Word DLLs, to create a Word document The application opens Microsoft Word, writes five copies of the
text specified by the someText variable, and saves the document in the file specified by the filename variable The
application leaves the instance of Word open
Trang 27Note: For an example that uses a NET System class directly and does not require any cousin NET code, see the
“Limita-tions” section of cfobject: NET object in the CFML Reference.
The second listing shows the WordCreator C# source code To run this application locally, you must compile this
class and the Microsoft Interop.Word.dll file, and place them in the C:\dotnet directory (Alternatively, you can put
them elsewhere and change the paths in the cfobject assembly attribute.) You might need additional or different
Microsoft DLL files, depending on the version of Microsoft Office that you have installed
The ColdFusion application contains the following code:
<cfdump label="WordCreator Class Dump" var="#wordCreator#">
<cfset someText = "ColdFusion created this sample document using Windows NET class methods
The text is long enough to appear in the Word file on multiple lines.">
<cfloop from=1 to=5 index =i>
// The commented-out lines may be needed on some systems in place of,
// or in addition to, the line that follows them.
public class WordCreator {
object readOnly = false;
object isVisible = true;
object missing = System.Reflection.Missing.Value;
object docType = 0;
object newTemplate = false;
object template = "normal.dot";
object format = WdSaveFormat.wdFormatDocument;
ApplicationClass app = new ApplicationClass();
private object fileName;
private Document doc;
Trang 28else doc.SaveAs(ref fileName, ref format, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
}
}
}
Advanced tools
Occasionally, the use of additional tools for generating proxies and running the NET extension software can be
helpful in some workflows
Using the jnbproxy command
You can use the jnbproxy command-line tool as an alternative to the jnbproxyGui program, to generate Java
proxies For moresinformation, see “Generating the Java proxy classes” on page 954
For example, you can use this command in a batch file to generate multiple proxy JAR files in a single operation
The jnbproxy command has the following format:
jnbproxy options classes
For example:
jnbproxy /al C:\dotNet\netdll\PrimitiveTypes.dll /d C:\dotNet\MyJavajars
/host localhost /n PrimitiveTypes /nj /pd j2n /port 6085 /pro b
Trang 29The following table lists the options that you can use To create proxies on a system that is running ColdFusion, use
the /nj option and do not specify the /bp, /java, or /jp options
/al assemblylist Required Specifies a semicolon-separated series of file paths of NET assemblies
(DLL and EXE files) that contain the required NET classes.
/bp bcelpath Optional Use the CLASSPATH
envi-ronment variable to locate the file.
Specifies the path to the folder that contains the bcel.jar file
Ignored if you use the /nj option.
/cf Required Use the ColdFusion software license If you do not include this option,
your proxies are limited to a 30-day trial period.
/d directory Optional The current execution
direc-tory
Specifies the directory in which to write a JAR file with the generated proxies
/f classfile Optional Reads the classes from the specified text file, not the command line
For more information, see the JNBridge documentation.
/h Optional Lists the options and usage information Typing the command jnbproxy
with no options or arguments results in the same information
/host hostname Required Specifies the host on which the NET code is located This option can be a
host name or an IP address Normally, you specify localhost
/java javapath Optional Use the first java.exe file
found using the system PATH environment variable.
Specifies the path of the directory that contains the java.exe program to use when automatically starting Java
Ignored if you use the /nj option.
/jp jnbcorepath Optional Use, the CLASSPATH
envi-ronment variable.
Specifies the path of the folder containing the file jnbcore.jar
Ignored if you use the /nj option.
/ls Optional Generate and list the
proxies.
Lists all classes to be generated in support of the specified classes (see
“Supporting classes” on page 955 ), but don't generate the proxies.
/n name Optional Create a file named
jnbproxies.jar.
Specifies the name of the JAR file in which to put the proxies Do not specify the jar extension; the tool automatically adds it.
/nj Optional Start Java automatically Does not start Java automatically If you use this option, Java must be
running, and the /bp, /java, /jp, and /wd options, if present, are ignored.
/ns Optional Generate proxies for all
supporting classes.
Generates proxies for the classes specified on the command line (or class file) only, not for any supporting classes.
/pd Required Specifies the direction in which the proxies operate Must be j2n
/port portNum Required Specifies the port on which the NET side listens when generating the
proxies Must be an integer Normally this value is 6085.
/pro protocol Required Specifies the communication mechanism between the NET and Java
sides The valid values are:
• b TCP/binary
• h (HTTP/SOAP
/wd dir optional The system’s default
working directory.
Specifies the working directory for the JVM.
Ignored if the /nj option is present.
Trang 30ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
970
Classes
A space-separated sequence of fully qualified NET class names (for example,
CSharpDatatypes.PrimitiveTypes) for which proxies should be generated The proxies for System.Object and
System.Type are always generated, even if they are not listed in the class list
Passing data by reference and value
The proxy generators let you specify whether to pass parameters and return values by reference or by value
About passing by reference and value
When you pass data by reference, the information transferred between the Java Proxy and the NET side is a logical
pointer to the underlying NET object, which continues to reside on the NET side When you pass data by value, the
transferred information contains a copy of the contents of the NET object, which might or might not continue to
reside on the NET side after a function call Passing by reference and value have different advantages
When you pass data by reference, only changed values are passed between the Java proxy and the NET object
directly All other information is passed as reference to its representation in the corresponding objects Because the
reference is typically much smaller than the actual object, passing by reference is typically very fast Also, because
the reference points to a NET object that continues to exist on the NET side, if that NET object is updated, the
updates are immediately accessible to the proxy object on the Java side The disadvantage of reference proxies is that
any access to data in the underlying object (e.g., field or method accesses) requires a round trip from the Java side to
the NET side (where the information resides) and back to the Java side
When you pass data by value, a copy of the data is passed between NET and Java Because the data object itself is
typically bigger than a reference, passing an object by value takes longer than passing it by reference Also, the value
that is passed is a snapshot of the object taken at the time that it was passed The passed object maintains no
connection to the underlying NET object, therefore, the passed value does not reflect any updates to the underlying
.NET object that are made after the object is passed The advantage of passing data by value proxies is that all data
in the object is local to the Java side, and field accesses are very fast, because they do not require a round trip to the
.NET side and back to get the data
The choice of whether to use reference or value proxies depends on the desired semantics of the generated proxies,
and on performance
• In general, you should use reference proxies (the default), because they maintain the normal parameter-passing
semantics of Java and C#
• In general, you should use value proxies in any of the following cases:
• The class functions always must pass parameter values and return values back and forth
• The class object contains little data
• There will be frequent modification of the object data, and the object is either relatively small or the
frequency of accesses to data outweighs the time taken to transfer the object
Specifying the data passing method
When you use the JNBProxy.gui tool to generate proxies, you can designate which proxies should be reference and
which should be value The default proxy type is reference
To set the data passing method for a class, right-click on the class in the Exposed Proxies pane Select the desired
passing method from the list that appears After you select the passing method, the color of the proxy class changes,
to indicate its type: black for reference, or blue for value (public fields/properties style)
Trang 31Set the passing method for multiple proxy classes simultaneously
1 Select Project > Pass By Reference / Value from the menu bar
2 The Pass by Reference / Value dialog box lists all proxy classes in the Exposed Proxies pane Select the classes
whose passing value you want to set
3 Click the Reference or Value (Public fields/properties) button to associate the selected classes to the desired type
4 Repeat steps 2 and 3 to select multiple groups of classes and set their passing methods
5 Click OK
Determining and changing the NET version
If you get errors when using a NET object in your application, you may have version issues For example, many
Microsoft system classes were added in NET Version 2.0, including System.IO.DriveInfo and
System.Net.NetworkInformation.Ping For examples of these classes in applications, see “Using NET objects” on
page 964 and “Example: Using a NET class directly” on page 966, respectively
Use the following function to get the current NET version:
<cffunction name="GetDotNetVersion" returntype="string">
<cfset var seClass="">
<cfobject type=".NET" name="seClass" class="System.Environment">
<cfreturn seClass.Get_Version().ToString()>
</cffunction>
If the function reports that the active version is not the one you require, install or reinstall the correct version of the
.NET framework redistributable package on the system that runs ColdFusion Then reinstall the ColdFusion NET
extension so that it uses the correct NET version
Running the NET extension agent as an application
The ColdFusion 8 NET extension installer configures the NET-side extension agent to run automatically as the
ColdFusion 8 NET service You can also run the NET extension agent as an application
Run the NET extension agent as an application
1 Ensure you stopped the ColdFusion 8 NET service, if it was running
2 Open a command prompt window and navigate to the jnbridge directory On a stand-alone ColdFusion server
configuration, this directory is installDir\jnbridge On a system with a stand-alone NET extension installation, or a
J2EE or multiserver configuration, it is in the NETInstallDir\jnbridge directory, and the default installation
directory is C:\ColdFusonDotNetExtension
3 Enter the following command:
JNBDotNetSide
Trang 32Chapter 51: Integrating COM and
CORBA Objects in CFML Applications
You can invoke COM (Component Object Model) or DCOM (Distributed Component Object Model) and CORBA
(Common Object Request Broker) objects
Contents
About COM and CORBA 972
Creating and using objects 973
Getting started with COM and DCOM 974
Creating and using COM objects 977
Getting started with CORBA 985
Creating and using CORBA objects 985
CORBA example 991
About COM and CORBA
This section provides some basic information on COM and CORBA objects supported in ColdFusion and provides
resources for further inquiry
About objects
COM and CORBA are two of the object technologies supported by ColdFusion Other object technologies include
Java and ColdFusion components For more information on ColdFusion components see “Building and Using
ColdFusion Components” on page 158
An object is a self-contained module of data and its associated processing An object is a building block that you can
put together with other objects and integrate into ColdFusion code to create an application
An object is represented by a handle, or name Objects have properties that represent information Objects also
provide methods for manipulating the object and getting data from it The exact terms and rules for using objects
vary with the object technology
You create instances of objects using the cfobject tag or the CreateObject function You then use the object and
its methods in ColdFusion tags, functions, and expressions For more information on the ColdFusion syntax for
using objects, see “Creating and using objects” on page 973
About COM and DCOM
COM (Component Object Model) is a specification and a set of services defined by Microsoft to enable component
portability, reusability, and versioning DCOM (Distributed Component Object Model) is an implementation of
COM for distributed services, which allows access to components residing on a network
COM objects can reside locally or on any network node COM is supported on Microsoft Windows platforms
For more information on COM, go to the Microsoft COM website, www.microsoft.com/com
Trang 33About CORBA
CORBA (Common Object Request Broker Architecture) is a distributed computing model for object-oriented
appli-cations defined by the Object Management Group (OMG) In this model, an object is an encapsulated entity whose
services are accessed only through well-defined interfaces The location and implementation of each object is hidden
from the client requesting the services ColdFusion supports CORBA 2.3 on both Windows and UNIX
CORBA uses an Object Request Broker (ORB) to send requests from applications on one system to objects executing
on another system The ORB allows applications to interact in a distributed environment, independent of the
computer platforms on which they run and the languages in which they are implemented For example, a ColdFusion
application running on one system can communicate with an object that is implemented in C++ on another system
CORBA follows a client-server model The client invokes operations on objects that are managed by the server, and
the server replies to requests The ORB manages the communications between the client and the server using the
Internet Inter-ORB Protocol (IIOP)
Each CORBA object has an interface that is defined in the CORBA Interface Definition Language (IDL) The
CORBA IDL describes the operations that can be performed on the object, and the parameters of those operations
Clients do not have to know anything about how the interface is implemented to make requests
To request a service from the server, the client application gets a handle to the object from the ORB It uses the handle
to call the methods specified by the IDL interface definition The ORB passes the requests to the server, which
processes the requests and returns the results to the client
For information about CORBA, see the following OMG website, which is the main web repository for CORBA
infor-mation: www.omg.com
Creating and using objects
You use the cfobject tag or the CreateObject function to create a named instance of an object You use other
ColdFusion tags, such as cfset and cfoutput, to invoke the object’s properties and methods
The following sections provide information about creating and using objects that applies to both COM and CORBA
objects The examples assume a sample object named “obj”, and that the object has a property called “Property”, and
methods called “Method1”, “Method2”, and “Method3”
Creating objects
You create, or instantiate (create a named instance of) an object in ColdFusion with the cfobject tag or
CreateObject function The specific attributes or parameters that you use depend on the type of object you use,
and are described in detail in “Creating and using COM objects” on page 977 and “Creating CORBA objects” on
page 986 The following examples use a cfobject tag to create a COM object and a CreateObject function to
create a CORBA object:
<cfobject type="COM" action="Create" name="obj" class="sample.MyObject">
obj = CreateObject("CORBA", "d:\temp\tester.ior", "IOR", "Visibroker")
ColdFusion releases any object created by cfobject or CreateObject, or returned by other objects, at the end of
the ColdFusion page execution
Using properties
Use standard ColdFusion statements to access properties as follows:
Trang 34ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
974
1 To set a property, use a statement or cfset tag, such as the following:
<cfset obj.property = "somevalue">
2 To get a property, use a statement or cfset tag, such as the following:
<cfset value = obj.property>
As shown in this example, you do not use parentheses on the right side of the equation to get a property value
Calling methods
Object methods usually take zero or more arguments You send In arguments, whose values are not returned to the
caller by value You send Out and In,Out arguments, whose values are returned to the caller, by reference Arguments
sent by reference usually have their value changed by the object Some methods have return values, while others
might not
Use the following techniques to call methods:
• If the method has no arguments, follow the method name with empty parentheses, as in the following cfset tag:
<cfset retVal = obj.Method1()>
• If the method has one or more arguments, put the arguments in parentheses, separated by commas, as in the
following example, which has one integer argument and one string argument:
<cfset x = 23>
<cfset retVal = obj.Method1(x, "a string literal")>
• If the method has reference (Out or In,Out) arguments, use double quotation marks (") around the name of the
variable you are using for these arguments, as shown for the variable x in the following example:
<cfset x = 23>
<cfset retVal = obj.Method2("x","a string literal")>
<cfoutput> #x#</cfoutput>
In this example, if the object changes the value of x, it now contains a value other than 23
Calling nested objects
ColdFusion supports nested (scoped) object calls For example, if an object method returns another object, and you
must invoke a property or method on that object, you can use the syntax in either of the following examples:
<cfset prop = myObj.X.Property>
or
<cfset objX = myObj.X>
<cfset prop = objX.Property>
Getting started with COM and DCOM
ColdFusion is an automation (late-binding) COM client As a result, the COM object must support the IDispatch
interface, and arguments for methods and properties must be standard automation types Because ColdFusion is a
typeless language, it uses the object's type information to correctly set up the arguments on call invocations Any
ambiguity in the object's data types can lead to unexpected behavior
Trang 35In ColdFusion, you should only use server-side COM objects, which do not have a graphical user interface If your
ColdFusion application invokes an object with a graphical interface in a window, the component might appear on
the web server desktop, not on the user's desktop This can take up ColdFusion server threads and prevent further
web server requests from being serviced
ColdFusion can call Inproc, Local, or Remote COM objects The attributes specified in the cfobject tag determine
which type of object is called
COM requirements
To use COM components in your ColdFusion application, you need at least the following items:
• The COM objects (typically DLL or EXE files) that you want to use in your ColdFusion application pages These
components should allow late binding; that is, they should implement the IDispatch interface
• Microsoft OLE/COM Object Viewer, available from Microsoft at
www.microsoft.com/com/resources/oleview.asp This tool lets you view registered COM objects
Object Viewer lets you view an object's class information so that you can properly define the class attribute for
the cfobject tag It also displays the object’s supported interfaces, so you can discover the properties and
methods (for the IDispatch interface) of the object
Registering the object
After you acquire an object, you must register it with Windows for ColdFusion (or any other program) to find it
Some objects have setup programs that register objects automatically, while others require manual registration
You can register Inproc object servers (.dll or ocx files) manually by running the regsvr32.exe utility using the
following form:
regsvr32 c:\path\servername.dll
You typically register Local servers (.exe files) either by starting them or by specifying a command line parameters,
such as the following:
C:\pathname\servername.exe -register
Finding the component ProgID and methods
Your COM object supplier should provide documentation that explains each of the component's methods and the
ProgID If you do not have documentation, use either the ColdFusion cfdump tag or the OLE/COM Object Viewer
to view the component’s interface
Using the cfdump tag to view COM object interfaces
Effective with ColdFusion, the ColdFusion cfdump tag displays the following information about a COM object:
• Public methods
• Put properties
• Get properties
The method and property information includes the parameter or property types and whether they are in, out,
optional, or retval values The cfdump tag output does not include the object’s ProgID
Note: The dump header indicates the ColdFusion object class, which is coldfusion.runtime.com.ComProxy, and the
COM object CLSID.
Trang 36ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
976
Using the OLE/COM Object Viewer
The OLE/COM Object Viewer installation installs the executable, by default, as \mstools\bin\oleview.exe You use
the Object Viewer to retrieve a COM object’s ProgID, as well as its methods and properties
To find an object in the Object Viewer, it must be registered, as described in “Registering the object” on page 975
The Object Viewer retrieves all COM objects and controls from the Registry, and presents the information in a
simple format, sorted into groups for easy viewing
By selecting the category and then the component, you can see the ProgID of a COM object The Object Viewer also
provides access to options for the operation of the object
To view an object's properties:
1 Open the Object Viewer and scroll to the object that you want to examine
2 Select and expand the object in the left pane of the Object Viewer
3 Right-click the object to view it, including the TypeInfo
If you view the TypeInfo, you see the object's methods and properties, as shown in the following figure Some
objects do not have access to the TypeInfo area, which is determined when an object is built and by the language
used
Trang 37Creating and using COM objects
You must use the cfobject tag or the CreateObject function to create an instance of the COM object (component)
in ColdFusion before your application pages can invoke any methods or assign any properties in the component
For example, the following code uses the cfobject tag to create the Windows CDO (Collaborative Data Objects)
for NTS NewMail object to send mail:
<cfobject type="COM"
action="Create"
name="Mailer"
class="CDONTS.NewMail">
The following line shows how to use the corresponding CreateObject function in CFScript:
Mailer = CreateObject("COM", "CDONTS.NewMail");
The examples in later sections in this chapter use this object
Note: CDO is installed by default on all Windows NT and 2000 operating systems that have installed the Microsoft
SMTP server In Windows NT Server environments, the SMTP server is part of the Option Pack 4 setup In Windows
2000 Server and Workstation environments, it is bundled with the operating system For more information on CDO for
NTS, see http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/cdo/_olemsg_overview_of_cdo.htm.
The CDO for NTS NewMail component includes a number of methods and properties to perform a wide range of
mail-handling tasks (In the OLE/COM Object Viewer, methods and properties might be grouped together, so you
could find it difficult to distinguish between them at first.)
The CDO for NTS NewMail object includes the following properties:
You use these properties to define elements of your mail message The CDO for NTS NewMail object also includes
a send method which has a number of optional arguments to send messages
Connecting to COM objects
The action attribute of the cfobject tag provides the following two ways to connect to COM objects:
Create method: (cfobject action="Create") Takes a COM object, typically a DLL, and instantiates it prior to
invoking methods and assigning properties
Connect method: (cfobject action="Connect") Links to an object, typically an executable, that is already
running on the server
You can use the optional cfobject context attribute to specify the object context If you do not specify a context,
ColdFusion uses the setting in the Registry The following table describes the context attribute values:
Trang 38ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
978
Setting properties and invoking methods
The following example, which uses the sample Mailer COM object, shows how to assign properties to your mail
message and how to execute component methods to handle mail messages
In the example, form variables contain the method parameters and properties, such as the name of the recipient, the
desired e-mail address, and so on:
<! - First, create the object ->
<cfobject type="COM"
action="Create"
name="Mailer"
class="CDONTS.NewMail">
<! - Second, use the form variables from the user entry form to populate a number
of properties necessary to create and send the message ->
<cfset Mailer.From = "#Form.fromName#">
<cfset Mailer.To = "#Form.to#">
<cfset Mailer.Subject = "#Form.subject#">
<cfset Mailer.Importance = 2>
<cfset Mailer.Body = "#Form.body#">
<cfset Mailer.Cc = "#Form.cc#">
<! - Last, use the Send() method to send the message.
Invoking the Send() method destroys the object. ->
<cfset Mailer.Send()>
Note: Use the cftry and cfcatch tags to handle exceptions thrown by COM objects For more information on
exception handling, see “Handling runtime exceptions with ColdFusion tags” on page 258.
Releasing COM objects
By default, COM object resources are released when the Java garbage collector cleans them You can use the
ReleaseCOMObject function to immediately release resources if an object is no longer needed
Use the ReleaseCOMObject function to release COM objects that are launched as an external process, such as
Microsoft Excel The garbage collector might not clean these processes in a short time, resulting in multiple external
processes running, which drains system resources
If the COM object has an end method, such as a quit method that terminates the program, call this method before
you call the ReleaseComObject function If you use the ReleaseComObject function on an object that is in use, the
object is prematurely released and your application will get exceptions
Example
The following example creates a Microsoft Excel application object, uses it, then releases the object when it is no
longer needed:
Attribute value Description
InProc An in-process server object (typically a DLL) that is running in the same process space as the calling process,
such as ColdFusion.
local An out-of-process server object (typically an EXE file) that is running outside the ColdFusion process space but
running locally on the same server.
remote An out-of-process server object (typically an EXE file) that is running remotely on the network If you specify
remote , you must also use the server attribute to identify where the object resides.
Trang 39obj = CreateObject("Com", "excel.application.9");
//code that uses the object goes here
obj.quit();
ReleaseComObject(obj);
</cfscript>
General COM object considerations
When you use COM objects, consider the following to prevent and resolve errors:
• Ensuring correct threading
• Using input and output arguments
• Understanding common COM-related error messages
Ensuring correct threading
Improper threading can cause serious problems when using a COM object in ColdFusion Make sure that the object
is thread-safe An object is thread-safe if it can be called from many programming threads simultaneously, without
causing errors
Visual Basic ActiveX DLLs are typically not thread-safe If you use such a DLL in ColdFusion, you can make it
thread-safe by using the OLE/COM Object Viewer to change the object’s threading model to the Apartment model
If you are planning to store a reference to the COM object in the Application, Session, or Server scope, do not use
the Apartment threading model This threading model is intended to service only a single request If your application
requires you to store the object in any of these scopes, keep the object in the Both threading model, and lock all code
that accesses the object, as described in “Locking code with cflock” on page 289
Change the threading model of a COM Object
1 Open the OLE/COM Object Viewer
2 Select All Objects under Object Classes in the left pane
3 Locate your COM object The left pane lists these by name
4 Select your object
5 Select the Implementation tab in the right pane
6 Select the Inproc Server tab, below the App ID field
7 Select the Threading Model drop down menu and select Apartment or Both, as appropriate
Using input and output arguments
COM object method in arguments are passed by value The COM object gets a copy of the variable value, so you can
specify a ColdFusion variable without surrounding it with quotation marks
COM object out method arguments are passed by reference The COM object modifies the contents of the variable
on the calling page, so the calling page can use the resulting value To pass a variable by reference, surround the name
of an existing ColdFusion variable with quotation marks If the argument is a numeric type, assign the variable a valid
number before you make the call For example:
<cfset inStringArg="Hello Object">
<cfset outNumericArg=0>
Trang 40ADOBE COLDFUSION 8
ColdFusion Developer’s Guide
980
The string "Hello Object" is passed to the object's calculate method as an input argument The value of
outNu-mericArg is set by the method to a numeric value
Understanding common COM-related error messages
The following table described some error messages you might encounter when using COM objects:
Accessing Complex COM Objects using Java proxies
ColdFusion supports Java proxies to access COM objects If you do not create Java proxies in advance, ColdFusion
must dynamically discover the COM interface This technique can have two disadvantages:
• Dynamic discovery takes time and can reduce server performance with frequently used complex COM objects
• Dynamic discovery uses the IDispatcher interface to determine the COM object features, and might not handle
some complex COM interfaces
To overcome these problems, ColdFusion includes a utility, com2java.exe, that creates static Java stub proxy classes
for COM objects ColdFusion can use these Java stubs to access COM objects more efficiently than when it creates
the proxies dynamically Additionally, the com2java.exe utility can create stubs for features that the dynamic proxy
generator might miss
ColdFusion ships with pregenerated stubs for the Windows XP, Windows 2000, and Windows 97 editions of
Microsoft Excel, Microsoft Word, and Microsoft Access ColdFusion is configured to automatically use these stubs
If you create Java stub files for a COM object, you continue to use the cfobject tag with a type attribute value of
COM, or the CreateObject function with a first argument of COM, and you access the object properties and methods
as you normally do for COM objects in ColdFusion
Use the following steps to use the com2java.exe utility This procedure uses Microsoft Outlook as an example
To create Java stub files for COM objects:
1 Configure your system as follows:
a Ensure that a JDK (Java Development Kit) is correctly installed, including proper configuration of the
CLASSPATH and the command prompt PATH variable
b Add CF_root\lib\jintegra.jar to your CLASSPATH
2 Make a new directory for the Java stub files; for example:
Error Diagnostic Information
Error trying to create object specified in the tag
COM error 0x800401F3 Invalid class string.
The COM object is not registered or does not exist.
Error Diagnostic Information
Error trying to create object specified in the tag
COM error 0x80040154 Class not registered.
The COM object is not registered or does not exist This error usually occurs when
an object existed previously, but was uninstalled.
Error Diagnostic Information
Failed attempting to find "SOMEMETHOD"
prop-erty/method on the object COM error 0x80020006.
Unknown name
The COM object was instantiated correctly, but the method you specified does not exist.