Skip to main content
Participating Frequently
October 13, 2025
Question

Azure Service Bus Schedule a message broken?

  • October 13, 2025
  • 3 replies
  • 484 views

I'm adding service bus integration using the azureservicebus package in ColdFusion 2023 update 16. I can send messages to a queue but I haven't been able to schedule a message for later processing. I've followed the documentation here  https://helpx.adobe.com/coldfusion/using/integrate-coldfusion-azure-service-bus.html
I've copied the code sample from "Schedule a message" but I get an error every time: "coldfusion.runtime.java.MethodSelectionException: The scheduleMessageToQueue method was not found." Does this method exist in ColdFusion 2023?

 

Here's my simple example:

<cfscript>

    credentialAlias = "AzureServiceBusCredential";
    configAlias     = "AzureServiceBusConfiguration";
    sb = getCloudService(credentialAlias, configAlias);


    testQueue = sb.createQueue("testQueue");
    sendMessage = {
        messageBody = "This is a test message",
        messageProperties = {
            contentType = "text/plain",
            subject = "Test Message",
            correlationId = createUUID()
        }
    }
    // This works
    sendResponse = testQueue.sendMessage(sendMessage);


    myQueue = sb.createQueue("q_006");
    schedMessage = {
        "messageId" = "001",
        "messageBody" = "message body",
        "ScheduledEnqueueTimeUtc" = dateAdd("n", 10, now())
    }
    try {
        // this errors with "The scheduleMessageToQueue method was not found."
        scheduleResponse = sb.scheduleMessageToQueue(myQueue, schedMessage)

    } catch (any e) {
        writeLog(file = "azureErrors", text = e, type="Error");
    }
</cfscript>

 

    3 replies

    Participating Frequently
    October 14, 2025

    Thank you Charlie and BKBK for your advice. I did some dumping and determined that yes, despite the documentation having the example of 

    scheduleResponse = sb.scheduleMessageToQueue(myQueue, schedMessage)

    where myQueue is an object, the method does actually expect the string queue name.

    Changing the code to 

    scheduleResponse = sb.scheduleMessageToQueue("Q_006", schedMessage)

    gets me past the error of "scheduleMessageToQueue method was not found". 

    Now I get "Unknown Field : ScheduledEnqueueTimeUtc".

    I thought maybe the format of the time was the issue, even though the doc example had  "02/02/2020", so I dug into the Azure documentation and found it was expecting a DateTimeOffset: an ISO8601 datetime. 

    So, changing the parameter to be the string queue name, and formatting the send time as ISO8601: 

        schedMessage5 = {
            "messageId" = "005",
            "messageBody" = "message body",
            "ScheduledEnqueueTimeUtc" = dateTimeFormat(dateAdd("n", 10, now()), "iso")
        }
        try {
            scheduleResponse = sb.scheduleMessageToQueue("Q_006", schedMessage5);
        } catch (any e) {
            writeDump(e);
        }

    I get this error instead

    struct

    MessageUnknown Field : ScheduledEnqueueTimeUtc
    StackTracecoldfusion.cloud.validator.FieldValidationFailedException: Unknown Field : ScheduledEnqueueTimeUtc at coldfusion.cloud.util.ValidatorFiller.fillObject(ValidatorFiller.java:70) at coldfusion.cloud.util.ValidatorFiller.fillObject(ValidatorFiller.java:48) at coldfusion.cloud.azure.servicebus.ServiceBusClientImpl.scheduleMessage(ServiceBusClientImpl.java:456) at coldfusion.cloud.azure.servicebus.ServiceBusClientImpl.scheduleMessageToQueue(ServiceBusClientImpl.java:430) at jdk.internal.reflect.GeneratedMethodAccessor158.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at coldfusion.runtime.StructBean.invoke(StructBean.java:509) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:4248) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:4100) at cfbasicServiceBusTester2ecfm1289919878.runPage(/Users/lisarees/Documents/repos/mainsite/basicServiceBusTester.cfm:120) at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:251) at coldfusion.tagext.lang.IncludeTag.handlePageInvoke(IncludeTag.java:749) at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:578) at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65) at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:573) at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:43) at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) at coldfusion.filter.PathFilter.invoke(PathFilter.java:162) at coldfusion.filter.IpFilter.invoke(IpFilter.java:45) at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30) at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:97) at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28) at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:60) at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62) at coldfusion.CfmServlet.service(CfmServlet.java:231) at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:311) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:46) at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:47) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at coldfusion.inspect.weinre.MobileDeviceDomInspectionFilter.doFilter(MobileDeviceDomInspectionFilter.java:57) at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:47) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1826) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) at java.base/java.lang.Thread.run(Thread.java:842)
    Suppressedarray[empty]
    TagContextarray
    1struct
    COLUMN0
    IDCF_STRUCTBEAN
    LINE120
    RAW_TRACEat cfbasicServiceBusTester2ecfm1289919878.runPage(/Users/lisarees/Documents/repos/mainsite/basicServiceBusTester.cfm:120)
    TEMPLATE/Users/lisarees/Documents/repos/mainsite/basicServiceBusTester.cfm
    TYPECFML
    Typecoldfusion.cloud.validator.FieldValidationFailedException

     

    And since dumping the queue object showed a similar method 

    scheduleMessage(java.util.Map)

     

    I tried calling that method with an ISO8601 also 

    scheduleResponse = myQueue.scheduleMessage(schedMessage5);

      But got the same error message about "Unknown Field : ScheduledEnqueueTimeUtc"

     

    Luckily I don't actually need the scheduled message functionality, but maybe my exploration of it will be helpful to someone else.

    BKBK
    Community Expert
    Community Expert
    October 15, 2025

    @lisar36119501 , thanks for trying out the suggestions and for the update.

     

    I can tell you that the cause of the error

    Unknown Field : ScheduledEnqueueTimeUtc

    is the same as the cause of your original error:  

     

    In this case, the documentation makes an error in suggesting that ScheduledEnqueueTimeUtc is one of the standard keys of the Map object representing the message to be queued. It is not. So, remove it from the message struct.

     

    You can add the Scheduled Enqueue UTC Time only through the API itself. Internally, ColdFusion’s getCloudService() abstraction wraps Java's Azure Service Bus SDK (Software Development Kit).

    So you have to do something like this, for example

    /* 
    Here, create a date-time in UTC, complete with offset.
    Suppose it is called 'scheduledTimeUtc'
    */
    
    // Set the scheduled enqueue time (UTC)
    message.setScheduledEnqueueTime(scheduledTimeUtc);

     

    BKBK
    Community Expert
    Community Expert
    October 16, 2025
    BKBK
    Community Expert
    Community Expert
    October 14, 2025

    @lisar36119501 , I suspect that the cause of the error is myQueue. In your code, it is passed as a string argument. I can understand why. That is what ColdFusion's Azure Service Bus documentation suggests.

    However, it is unlikely for myQueue to be a string. My reasoning follows.

     

    ColdFusion's Azure Service Bus documentation contains examples such as

    tempQ = sb.createQueue("Queue18") 
    //writedump(tempQ) 
    mypath=tempQ.getPath() 

    which suggest that createQueue() returns a complex object. In addition, the documentation says that the syntax for scheduleMessageToQueue is:

    scheduleMessageToQueue(String queuePath, Map metadata)


    In your code, schedMessage is a struct, hence of type CaseInsensitiveMap. That's fine. But myQueue is probably not a string. As I have shown, myQueue is a complex object which has the queue-path as one of its attributes. Hence the following suggestions.

     

    1.  The documentation says that a queue's path is given by myQueue.getPath(). So use myQueue.getPath() in place of myQueue.
      myQueue = sb.createQueue("q_006");
          schedMessage = {
              "messageId" = "001",
              "messageBody" = "message body",
              "ScheduledEnqueueTimeUtc" = dateAdd("n", 10, now())
          };
          try {
              scheduleResponse = sb.scheduleMessageToQueue(myQueue.getPath(), schedMessage);
          } catch (any e) {
              writeLog(file = "azureErrors", text = e, type="Error");
          }
    2.  If the above suggestion doesn't work, find an alternative way to get the queue-path.
    /** 
    Look for ways to obtain the queue-path from 
    the information in the metadata or the queue object.  
    **/
    myQueue = sb.createQueue("q_006");
    writedump(var="#getMetadata(myQueue)#", label="GetMetadata(myQueue)");
    writedump(var="#myQueue#", label="myQueue");
    
    /* What do the dumps tell you? Here I have assumed the dumps say the path is myQueue.name */
    myQueuePath = myQueue.name;
    
        schedMessage = {
            "messageId" = "001",
            "messageBody" = "message body",
            "ScheduledEnqueueTimeUtc" = dateAdd("n", 10, now())
        }
        try {
            // this errors with "The scheduleMessageToQueue method was not found."
            scheduleResponse = sb.scheduleMessageToQueue(myQueuePath, schedMessage)
    
        } catch (any e) {
            writeLog(file = "azureErrors", text = e, type="Error");
        }

     

    Charlie Arehart
    Community Expert
    Community Expert
    October 13, 2025

    Lisa, while I've never used the ASB feature, and I'm reading this on my phone, I might still be able to offer a useful suggestion. And although your code looks like it SHOULD work compared to the docs, here are two things to consider.

     

    First, are you running this that you feel you must rely on writelog, because you can't produce output to the screen? Can you arrange to call it in such a way that you can? If so, it will simply make diagnosing things easier. 

     

    For example, what do you see if you writedump(sb)?  That will list all the methods of that cfc instance, including their arguments. Indeed, then dump also your myqueue and schedmessage vars. Despite what our eyes tell us from your code, those may hold something that's somehow unexpected. 

     

    Finally, there may also be more useful detail in the error than what your writelog is reflecting. How about dumping the e var within the catch?

     

    Or (sometimes better still) remove the try/catch and just let the normal cf error dump to screen. Another benefit of that is you may see more detail in cf's exception.log (which may not be written to when you catch an error).

     

    Of course, you can also tell writedump/cfdump to write its output to a file instead of the screen, if you must for some reason. 

     

    Let us know what you find, or better if you may be able to use that info to resolve the problem on your own. Or maybe someone else will see a different solution for you. 

    /Charlie (troubleshooter, carehart. org)