Whatever message this page gives is out now! Go check it out!

Enhanced Java integration in ColdFusion

Last update:
Jun 5, 2026

Integrating Java libraries

ColdFusion lets you load Java libraries from a custom path that you specify. In the previous versions, you use Java libraries placed in the lib directory of ColdFusion. Those libraries are not application-specific and adding a Java library or updating an existing library is not easy. You also have to restart ColdFusion.
ColdFusion lets you place the Java libraries for an application in a directory of your choice. You specify the path of this directory in the Application.cfc. Then, use the libraries in your application by creating a cfobject of Java type.

Specifying custom Java library path in the Application.cfc without dynamic loading

Specify the custom path from where you want to load the Java library in the Application.cfc. of your project.
In this case, if there is an update to the file, you have to restart ColdFusion to load the updated files.
Add the following entry in this file:
THIS.javaSettings = {LoadPaths = [".\java_lib\",".\java\myjar.jar"], loadColdFusionClassPath = true, reloadOnChange = false}

Parameters

ParameterDescription
loadPaths
An array of paths to the directories that contain Java classes or JAR files.You can also provide the path to a JAR or a class. If the paths are not resolved, an error occurs.
loadColdFusionClassPath
Indicates whether to load the classes from the ColdFusion lib directory. The default value is false.
reloadOnChange
Indicates whether to reload the updated classes and JARs dynamically, without restarting ColdFusion. The default value is false.

Specifying the custom Java library path in the Application.cfc with dynamic loading

Specify the custom path from where you want to load the Java library in the Application.cfc of your project.
In this case, if there is an update to the file, you need not restart ColdFusion to load the updated files.
Add the following entry in this file:
THIS.javaSettings = {LoadPaths = [".\java_lib\",".\java\myjar.jar"], loadColdFusionClassPath = true, reloadOnChange= true, watchInterval = 100, watchExtensions = "jar,class,xml"}

Parameters

ParameterDescription
loadPaths
An array of paths to the directories that contain Java classes or JAR files.You can also provide the path to a JAR or a class. If the paths are not resolved, an error occurs.
loadColdFusionClassPath
Indicates whether to load the classes from the ColdFusion lib directory. The default value is false.
reloadOnChange
Indicates whether to reload the updated classes and JARs dynamically, without restarting ColdFusion. The default value is false.
watchInterval
Specifies the time interval in seconds after which to verify any change in the class files or JAR files. This attribute is applicable only if the reloadOnChange attribute is set to true. The default value is 60 seconds.
watchExtensions
Specifies the extensions of the files to monitor for changes. By default, only .class and .jar files are monitored.

Using a Java class

Save the Java class files or JARs in the directory that you specified in the Application.cfc. Then, access the methods in the JARs or class files by creating a cfobject of Java type.
In this example, you create a Java class and access a method in the Java class in the sample application.
  1. Create a Java file, Test.java.
    public class Test { public String testJava() { return "Hello Java!!"; } }
  2. Compile the Java file using a Java compiler.
  3. Add the following entry to the Application.cfcof your project:
    <cfset THIS.javaSettings = {LoadPaths = ["/myJava/lib"],reloadOnChange=true,watchInterval=30}/>
  4. Create the following directory structure in your application folder:
    /myJava/lib
  5. Copy the Test.class file to the /myJava/lib folder.
  6. Create a CFM file with the following content.
    <cfobject type="java" class="Test" name="myObj"> <cfset y = myObj.init()> <cfoutput > #y.testJava()# </cfoutput>
  7. Deploy the application and access the CFM file.

Using the CFC Proxy

Using the CFC Proxy, you can access a ColdFusion component from Java classes. To call CFC, ColdFusion class loader must be the current class loader. For example, the following code creates a CFC Proxy from the file location provided:
CFCProxy(String fully-qualified-path-of-CFC-file)
Similarly, the following code creates a CFC Proxy from the file location provided. It also initializes the This scope of the CFC with the name value pairs.
CFCProxy(String fully-qualified-path-of-CFC-file name-value-pairs)
ColdFusion 10 introduced a new argument in CFProxy classes, directInvoke. If this argument is set true, the request does not go through the ColdFusion Filter chain. It results in improved performance. The following example creates a Java class that access a ColdFusion component using CFC Proxy.
  1. Create the following Java class.
    import coldfusion.cfc.CFCProxy; public class CFCInvoker { public String directInvoke(String cfcPath) { String myMessage = ""; try { CFCProxy myCFC = new CFCProxy(cfcPath, true); Object[] myArgs = { "Hello" }; myMessage = (String)myCFC.invoke("getData", myArgs); } catch (Throwable e) { e.printStackTrace(); } return myMessage; } }
  2. Compile the file and place it in the lib directory of the project folder.
  3. Create a ColdFusion component as follows:
    <cfcomponent> <cffunction name="getData" returntype="string"> <cfargument name="msg" required="Yes"> <cfreturn msg & "Java" /> </cffunction> </cfcomponent>
  4. In the application.cfc, add the following entry:
    THIS.javaSettings = {LoadPaths = ["/lib"],reloadOnChange= true,loadColdFusionClassPath=true};
  5. Create a CFM file to print the output:
    <cfobject action="create" type="java" class="CFCInvoker" name="x"> <cfset cfcPath = "C:\ColdFusion10\cfusion\wwwroot\Project\name.cfc"/> <cfset y = x.directInvoke2(cfcPath)> <cfoutput>#y#</cfoutput>
  6. Access the CFM file.

Using the createDynamicProxy function

The function createDynamicProxy creates a dynamic proxy of the ColdFusion component that is passed to a Java library. Dynamic proxy lets you pass ColdFusion components to Java objects. Java objects can work with the ColdFusion components seamlessly as if they are native Java objects.  To create a dynamic proxy, provide the name of the ColdFusion component and an array of Java interfaces. The component is treated as if it implements the specified interfaces. Create a dynamic proxy as follows:
createDynamicProxy("fullyQualifiedNameOfCFC", ["interfaceName"]);
Specify the following parameters:
  • Fully qualified name of the ColdFusion component or a CFC instance.
  • An array of Java interfaces for which you want to create the dynamic proxy.

Creating a dynamic proxy

The following example shows how to create a Java interface. Interface defines a method. A ColdFusion component implements the method as a ColdFusion function. The dynamic proxy of the ColdFusion component calls a Java class by passing the object of the interface. It then calls the method in ColdFusion as if it is a native Java class.
  1. Create a Java interface, MyInterface.
    public interface MyInterface { public String sayHello(); }
  2. Compile the Java file and place it in a directory, lib.
  3. Create a Java class, InvokeHelloProxy, that calls the ColdFusion object using the instance of the interface.The constructor, InvokeHelloProxy, creates an object of MyInterface. The invokeHello() method calls the sayHello()method using the object.
    public class InvokeHelloProxy { private MyInterface myInterface; public InvokeHelloProxy(MyInterface x) { this.myInterface = x; } public String invokeHello() { return myInterface.sayHello(); } }
  4. Compile the Java file and place it in a directory, lib.
  5. Create a CFC file, HelloWorld.cfc, that implements the method defined in the interface and save it in a directory, cfc.
    <cfcomponent> <cffunction name="sayHello" returntype="string"> <cfreturn "Hello World!!!!"> </cffunction> </cfcomponent>
  6. Add the following code in the Application.cfc.{{}}
    <cfset THIS.javaSettings = {LoadPaths = ["/lib"],reloadOnChange=true,watchInterval=10}/>
  7. Add a CFM file that creates a dynamic proxy for HelloWorld as interface, MyInterface. Create an object of InvokeHelloProxy class and initiate the class.The code creates a dynamic proxy of MyInterface.
    <cfset dynInstnace = createDynamicProxy("cfc.HelloWorld", ["MyInterface"])> <cfset x = createObject("java","InvokeHelloProxy").init(dynInstnace)> <cfset y = x.invokeHello()> <cfoutput>#y#</cfoutput>
    Example: using a CFC instance
    <cfset instance=new cfc.helloWorld()> <cfset dynInstnace = createDynamicProxy(instance, ["MyInterface"])> <cfset x = createObject("java","InvokeHelloProxy").init(dynInstnace)> <cfset y = x.invokeHello()> <cfoutput>#y#</cfoutput>
  8. Deploy the application and access the CFM file.

Passing CFML functions to Java lambdas (ColdFusion 2025.0.08 and later)

Modern Java APIs make extensive use of lambdas and functional interfaces such as `Runnable`, `Comparator`, and single‑method listener interfaces. In earlier versions of ColdFusion, integrating with these APIs often required creating Java classes or using dynamic proxies in CFML, even when the interface had only a single method.
Starting in ColdFusion 2025.0.08, you can:
  • Pass CFML functions and closures directly to Java methods
  • Pass CFML Lambda expressions to functions expecting Java Lambda Expressions.
  • Work with Java APIs that use streams and callbacks without writing boilerplate Java code.
ColdFusion automatically creates a Java proxy for the CFML function and maps it to the appropriate functional interface based on the Java method signature.
How it works
A Java functional interface is an interface that defines exactly one abstract method, for example:
  • `java.lang.Runnable` → void run()
  • `java.util.Comparator<T>` → int compare(T o1, T o2)
  • Custom interfaces such as:
java
  public interface StateChangeListener {
      void onStateChange(State oldState, State newState);
  }
When you pass a CFML function, closure, or lambda expression as an argument to a Java method that expects a functional interface, ColdFusion:
  1. Looks at the Java method’s parameter type (for example, StateChangeListener or Predicate<String>).
  2. Uses the interface’s single abstract method (for example, onStateChange, test, or run) to determine the expected arguments.
  3. Creates a Java proxy that delegates calls to your CFML function.
This eliminates the need to:
  • Create intermediate CFCs solely to implement a Java interface.
  • Use createDynamicProxy() manually for common functional‑interface use cases.
  • Compile custom Java classes just to wire up callbacks.
Example: mapping CFML functions to listener interfaces
Consider the following Java interface and class:
// Java interface
public interface StateChangeListener {
    void onStateChange(State oldState, State newState);
}

// Java class that accepts the interface
public class StateOwner {
    public void addStateListener(StateChangeListener listener) {
        // ...
    }
}
      
In ColdFusion, you can pass a CFML function or closure directly:
<cfscript>
// Create the Java object
stateOwner = createObject("java", "com.example.StateOwner");

// Pass a CFML function where Java expects a StateChangeListener
stateOwner.addStateListener( function(oldState, newState) {
    writeOutput(
        "State changed from " & oldState.toString() &
        " to " & newState.toString() & "<br>"
    );
});
</cfscript>       
      
ColdFusion detects that addStateListener expects a single‑method interface (StateChangeListener) and creates a Java proxy that calls your CFML function when Java invokes onStateChange. You can use the same pattern with any Java API that accepts a functional interface.
Example: using CFML lambdas with Java streams
Many Java libraries expose streams and expect you to provide lambdas for operations such as filter, map, and forEach. ColdFusion 2025.1 lets you pass CFML lambdas directly to these operations.
The following code snippet is now supported:
<cfscript>
    // Create a Java ArrayList
    list = createObject("java", "java.util.ArrayList").init();
    list.add("apple");
    list.add("banana");
    list.add("chery");

    // Get Java stream from the list
    stream = list.stream();

    // Apply filter and collect results
    collector = createObject("java", "java.util.stream.Collectors");
    upperList = stream
        .filter(input => { return input.length() == 6; })
        .collect(collector.toList());

    // Validate output without writeDump
    writeOutput(upperList.size() & "|" & upperList.contains("banana"));
    // Output: 1|true
</cfscript>
In this example:
  • input => { return input.length() == 6; } is a CFML lambda expression.
  • Java expects a java.util.function.Predicate<String> for filter.
  • ColdFusion automatically maps the CFML lambda to the Java Predicate interface and calls the CFML code when Java invokes test.
You can use the same approach for:
  • forEach (for example, stream.forEach(item => { ... }))
  • map (for example, stream.map(item => { return item.toUpperCase(); }))
  • Other functional interfaces in the java.util.function package.
Example: CFML closures as Java Runnable
You can also pass CFML closures to Java methods that expect a Runnable:
<cfscript>
executor = createObject("java", "com.example.Executor");

// Java method: public void executeAsync(Runnable task)
executor.executeAsync( function() {
    writeOutput("Running in background<br>");
});
</cfscript>
ColdFusion wraps the CFML closure as a Runnable implementation and invokes it when Java calls run().
Example
<cfscript>
    CompletableFuture = createObject("java", "java.util.concurrent.CompletableFuture");

    future = CompletableFuture
            .supplyAsync(() => { return "hello world"; })
            .thenApply(val => { return uCase(val); })
            .thenApply(val => { return len(val); });

    writeOutput(future.get());
</cfscript>

Share this page

Was this page helpful?
We're glad. Tell us how this page helped.
We're sorry. Can you tell us what didn't work for you?
Thank you for your feedback. Your response will help improve this page.

On this page