ColdFusion runAsync方法无法实例化Bean的问题排查
ColdFusion 2018异步环境实例化Bean抛出NullPointerException问题
在ColdFusion 2018(版本2018.0.08.330106)中,基础示例代码在runAsync异步方法内实例化Bean时抛出NullPointerException,但同步环境下无此问题。请问异步环境中实例化Bean是否存在相关限制?
Bean代码
<cfcomponent displayname="TestBean" hint="I model a single TestBean." output="false"> <!--- 构造函数 ---> <cffunction name="init" access="public" output="false" returntype="TestBean"> <cfscript> return(this); </cfscript> </cffunction> </cfcomponent>
测试CFM代码
<cfscript> arErrors= []; initiatedAsyncProcesses = []; initiatedAsyncProcesses.append(runAsync(function() { local.TestBean = new TestBean(); }).error( function(error){arrayAppend(arErrors, error)} )); // 等待错误捕获 sleep(100); writedump(arErrors); </cfscript> Complete
抛出的错误信息
==> /opt/coldfusion2018/cfusion/logs/exception.log <== "Error","pool-10-thread-12","10/03/23","10:21:07","","java.lang.NullPointerException" java.util.concurrent.ExecutionException: java.lang.NullPointerException at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191) at coldfusion.runtime.async.Future.get(Future.java:146) at coldfusion.runtime.async.CallableUDFMethod.call(CallableUDFMethod.java:90) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: java.lang.NullPointerException
问题原因与解决方案
ColdFusion 2018的runAsync异步线程默认不会继承主线程的页面上下文(Page Context),而CFML组件通过new关键字实例化时,依赖页面上下文完成组件路径解析、初始化资源等操作。异步线程缺少有效页面上下文时,就会触发NullPointerException。
针对该问题,有两种可行解决方式:
- 方式一:显式传递页面上下文
修改runAsync调用,通过withPageContext()方法将主线程的页面上下文传入异步任务:initiatedAsyncProcesses.append(runAsync(function() { local.TestBean = new TestBean(); }).withPageContext().error( function(error){arrayAppend(arErrors, error)} )); - 方式二:使用
createObject替代new关键字createObject函数不依赖页面上下文即可加载并实例化组件,适合异步场景:local.TestBean = createObject("component", "TestBean").init();
另外,ColdFusion 2018的部分旧版本存在异步线程上下文相关bug,升级到2018.0.15及以上补丁版本也能解决这类异常。
内容的提问来源于stack exchange,提问作者user1002794
相关产品推荐
相关产品推荐

