Cast CFML function to Java function


Playing around with Java thread pools I’ve run into the problem of using the CFML function as an argument for the Java function.

Lucee is not casting lucee.runtime.type.Closure into the java function, e.g. java.lang.Runnable or java.util.function.Function. Manually casting using the javaCast throws an error:
"Can't cast Object type [user defined function (closure_2s2)] to a value of type [java.lang.runnable]"

It is possible to cast Lucee function to Java?


In order to do this, you must create a CFC that implements the functional interface the Java lib requires and then use createDynamicProxy to pass it in. You can pass your UDF to the CFC to wrap it. Ortus has several libraries doing this including rabbitmq sdk, cbstreams, and cbfutures.

The next problem you’ll have is that none of your application or request variables will be available inside the threads created by the java threadpool. We’ve also mostly solved that for Lucee and Adobe in the libraries above.

The fact that passing closures as lambdas and setting up the pagecontext in java threads is still so hard, really annoys me. As a JVM language, CF shouldn’t require us to struggle so hard to do these things. We asked Lucee to help with the UDF->lambda issue about three years ago and were told it would be done in Lucee 6, which as far as I can tell is still at least a year out so it’s been pretty much useless.

Thanks for your detailed response. I will take a look at how it is implemented in those libs.

Actually, depending on what you’re doing, you may just be able to use the async stuff we’ve written. It’s all based on Java’s concurrent lib.

You don’t have to use ColdBox. We also include our async lib in LogBox, CacheBox, and WireBox. Read through those docs and see if the executor thread pools we’ve wrapped is what you need.

1 Like