JMS Queue Sender

Publishes a message to a JMS queue. In practice the destination almost never resolves, because the rule reads a config key the activity's schema never puts it under.

Caveat com.tibco.plugin.jms.JMSQueueSendActivity

What it does in BusinessWorks

Sends one message to a JMS queue over a shared connection resource. The destination, delivery mode, priority and message type live under <config><SessionAttributes>, the queue itself is usually a deployment-time substitution variable rather than a literal, and the input mapping builds the message body plus any headers the activity is configured to set explicitly.

The activity is fire-and-forget: it does not wait for a reply, and its own output carries only the send confirmation, not a response payload.

The Camel equivalent

BusinessWorks 5.process
<pd:activity name="JMS Queue Sender">
  <pd:type>com.tibco.plugin.jms.JMSQueueSendActivity
  </pd:type>
  <config>
    <PermittedMessageType>XML Text
    </PermittedMessageType>
    <SessionAttributes>
      <transacted>false</transacted>
      <destination>%%orders/inboundQueue%%
      </destination>
    </SessionAttributes>
    <ConnectionReference>
      /shared/JMS Connection.sharedjmscon
    </ConnectionReference>
  </config>
  <pd:inputBindings>
    <Body>
      <destinationQueue>
        <xsl:value-of select=
          "$_globalVariables/glob:GlobalVariables
           /orders/queueName"/>
      </destinationQueue>
    </Body>
  </pd:inputBindings>
</pd:activity>
Apache CamelJava DSL, generated
// the whole activity, as emitted, quoted
// from the generator's own source string
.log(LoggingLevel.WARN, "TODO_HUMAN: "
    + "unresolved JMS queue destination "
    + "(source had no destination attr / "
    + "inputBinding) — wire real queue/topic "
    + "or remove this step")

Where the semantics diverge

The destination is read from the wrong place, and this is not a corner case. The rule looks for a top-level destination key on the activity’s configuration. TIBCO Designer never puts it there: every JMS Queue Sender in the source nests it one level down, inside SessionAttributes. The parser captures SessionAttributes as a single serialised block under its own key, so the rule’s lookup finds nothing and falls back to a heuristic over the input bindings, hunting for a binding whose path mentions “queue” or “topic” and whose value literally contains the word queue or topic followed by a space and a token. XSLT that reaches for a global variable, which is the common shape, does not produce that literal text. Both failure modes are visible in a real run of this toolchain: not one of its outputs contains a working to("jms:...") call or a resolved direct: hop from this rule, and the unresolved-destination warning above appears repeatedly.

When it fails, nothing is sent, and nothing else runs either. The unresolved path returns after the warning. There is no .to(...), no delay, no continuation script. The step simply stops producing anything, and whatever came after it in the source process picks up as if the send had already happened.

Delivery mode, priority and transacted are never read, resolved or not. A queue configured for persistent, prioritised delivery inside a transacted session comes out with none of that: Camel’s default JMS component settings apply instead, silently.

Wire the real destination for every JMS Queue Sender by hand: either as a Camel endpoint URI once you know the physical queue name, or through the QueueRouteIndex mechanism the generator already has, which resolves a destination straight to a direct: hop into the component that owns it when the destination is known statically enough to be indexed.

What the toolchain does

A rule with an internal condition, so the report counts it as a caveat rather than a plain translation, and the finding above is why: the rule first tries an index lookup keyed on the destination it manages to infer, falls back to a heuristic when nothing usable was found, and emits a TODO_HUMAN warning when even the heuristic comes up empty, which the config-nesting mismatch above means it does for the destination path Designer actually writes.

Where the destination is known and unique, the rule replaces the send outright with a direct: hop into the component the message was really headed for, dropping the JMS transport entirely and noting the substitution as a step description. Where more than one component could own the same destination, it warns instead of guessing.