Set Shared Variable

Writes engine-wide state that outlives the job. The generator turns it into an exchange property named after the activity, so nothing outside that one exchange can see it.

Caveat com.tibco.pe.core.SetSharedVariableActivity

What it does in BusinessWorks

Writes to a Shared Variable resource, referenced by path in <config><variableConfig>. The resource, not the activity, decides what the write means. A Job Shared Variable is a per-job copy initialised from the resource’s default, so a write is visible to every activity in that job and to nobody else. A plain Shared Variable is engine-wide: one value, shared by every job in the engine, surviving between jobs, and persisted across restarts when the resource is marked persistent.

Engine-wide writes are not atomic. Two jobs writing the same variable interleave, which is why the pattern in the field is a Set Shared Variable wrapped in a Critical Section, and why a migration has to look at both together rather than at either on its own.

The Camel equivalent

BusinessWorks 5.process
<pd:activity name="SetVariable">
  <pd:type>com.tibco.pe.core.SetSharedVariableActivity
  </pd:type>
  <pd:resourceType>ae.activities.setSharedVariable
  </pd:resourceType>
  <config>
    <variableConfig>/config/PoolState.sharedvariable
    </variableConfig>
  </config>
  <pd:inputBindings>
    <pool>
      <status>
        <xsl:value-of select="'READY'"/>
      </status>
    </pool>
  </pd:inputBindings>
</pd:activity>
Apache CamelJava DSL, generated
// the whole activity, as emitted
.setProperty("SetVariable", constant(
  "<xsl:value-of select=\"'READY'\" xmlns:xsl=\"http:
   //www.w3.org/1999/XSL/Transform\"/>"))

Where the semantics diverge

Engine scope becomes exchange scope. An exchange property lives for one message. Whatever the variable was for, whether a connection pool state, a cache, a circuit breaker counter or a sequence number, stops being shared the moment it is translated. Nothing in the output fails; the state simply never crosses from one message to the next.

The resource path is never read. The rule keys the property on the activity’s own name, not on variableConfig. Two processes writing the same resource write two differently named properties on two different exchanges, and a Get Shared Variable reads a third name again. The link between writer and reader is gone from the output, not merely weakened.

Persistence disappears silently. A variable marked persistent in BusinessWorks survives an engine restart. There is no equivalent in the generated route and no marker to say so.

The value is the XSLT source, not its result. As with Assign, the rule passes the first input binding’s source text into constant(...), so the property holds <xsl:value-of .../> as a string. Only the first leaf survives, and binding values are truncated at 800 characters during parsing.

The decision this forces is about the state itself, not about the syntax. Ask what the variable actually held. Configuration read once at startup belongs in application.yaml. State shared between messages needs a real store: a cache, a database row, an idempotent repository, and the Critical Section that guarded it needs replacing at the same time.

What the toolchain does

The same rule as Assign, with the same internal conditions, which is why the report counts it as a caveat. It emits .setProperty("<sanitised activity name>", constant("<first binding value>")), falling back to simple("${body}") when the activity has no usable binding. It does not read variableConfig, does not distinguish a job-shared variable from an engine-wide one, and emits no marker for either.