Upgrading SOA BPEL processes: the MDS, namespace and XSD changes
Last updated 7 min read
TL;DR
The SOA runtime upgrades cleanly; the BPEL composites you customized on top of it are a separate, hands-on piece of work. On every AP-workflow SOA upgrade we have run, the failures cluster in three places: local XSD references that must be re-pointed to the MDS through oramds, namespace prefixes that collide when the new baseline is merged in, and shared transform blocks that were re-authored between releases and cannot be cherry-picked line by line. A diff tool shows what differs; it does not tell you which side is right.
If you are planning an Oracle SOA Suite upgrade, and on 12c heading toward the December 2026 support date you are, there is a part of the project the platform guides gloss over: your BPEL processes do not upgrade themselves. The runtime moves cleanly. The composites you built and customized on top of it are a separate piece of work, and they fail in specific, predictable ways when treated as a straight copy-forward.
Across the AP-workflow SOA estates we have carried between releases, the failures cluster around three things: how XSD schemas are referenced, how namespace prefixes collide, and what a diff tool will silently overwrite. This is the runbook.
Rule one: back up, then merge on a copy against a diff
Before touching a single .bpel file, take a full backup of the old processes. Then get the new version's processes (the ones that ship with the target release or your accelerator baseline) and use them as the reference for a three-way merge against your customized ones.
The merge is not identical in every environment, because the amount and shape of customization differs, but the classes of change below apply every time. Use a real comparison tool (WinMerge, ExamDiff, BeyondCompare), do a folder-level compare first and then file-level. The tool tells you what differs. It does not tell you which side is right, and that judgment is the whole job.
Change 1: XSD references move to the MDS through oramds
This is the big one, and the change most likely to leave you with composites that will not compile.
In older SOA (11.1.1.5 and earlier in this lineage), BPEL processes referenced their XSD definitions as files local to the project:
schemaLocation="xsd/WorkflowTask.xsd"
schemaLocation="WorkflowTask.xsd"
From 11.1.1.6 onward, and this is the same architectural shift you carry into every later release, schema definitions should come from the Metadata Services (MDS) repository SOA uses, referenced with the oramds identifier. The compiler can then verify that every reference is one the runtime understands, instead of trusting a copy sitting in the project:
schemaLocation="oramds:///soa/shared/workflow/WorkflowTask.xsd"
Every local reference has to be re-pointed. WorkflowTask.xsd, WorkflowCommon.xsd and the rest of the shared workflow schemas move to their oramds:///soa/shared/... counterparts. Practically, that also means the .adf directory, which holds adf-config.xml with the MDS reference, has to be copied into the project. It sits at the top of the directory listing and it is easy to miss because it is a dot-directory.
Miss one local schemaLocation and you do not get a clean error pointing at it; you get a compile failure that sends you hunting. Grep every process for schemaLocation= before you deploy.
Change 2: namespace prefixes collide during the merge
This is the one a diff tool leads you into. The new baseline processes often add namespaces that were not in your older version. A recurring example is the comment-types namespace introduced in the newer processes:
xmlns:ns5="http://xmlns.oracle.com/imaging/axf/commentTypes"
That line assumes ns5 is free. If your process was customized and something else already claimed ns5, you have a collision, and merging the new line verbatim silently breaks whichever binding loses. Two choices:
- Renumber the incoming namespace (
ns5tons11, say) and update every reference to it in the new process, or - Renumber the conflicting namespace on your side.
Option 1 is almost always less work: there are usually a handful of references to the newly added namespace, against a web of references to a customization that has been in place for years. But you have to look. Check the xmlns: declarations at the top of each .bpel file and reconcile them by hand. A blind "take theirs" or "take mine" will burn you here.
Change 3: shared transform blocks changed shape
Some logic did not just move; it was re-authored between versions, and you cannot cherry-pick lines. The comment-to-task copy is the canonical case. The old processes carry a plain copy:
<assign name="Copy_UserCommentsToTask">
<bpelx:copyList>
<bpelx:from variable="UserComments" query="/client:userComments/task:userComment"/>
<bpelx:to variable="initiateTaskInput" part="payload"
query="/taskservice:initiateTask/task:task/task:userComment"/>
</bpelx:copyList>
</assign>
The newer processes replace it entirely with a transformation that runs an XSLT and guards against empty comments:
<assign name="Transform_CopyCommentsToTask"
bpelx:skipCondition="bpws:getVariableData('UserComments','/client:userComments') = """>
<bpelx:annotation><bpelx:pattern>transformation</bpelx:pattern></bpelx:annotation>
<copy>
<from expression="ora:doXSLTransformForDoc('xsl/Transformation_CopyCommentsToNewTask.xsl', $initiateTaskInput.payload, 'UserComments', $UserComments)"/>
<to variable="initiateTaskInput" part="payload"/>
</copy>
</assign>
The trap is the /client namespace. Whether the replacement works depends on what /client resolves to in your process, and a customized process may bind it to something the reference does not expect. Before pasting the new block into AccountDistribution.bpel, AssignUser.bpel, RequestForInvoiceInformation.bpel, Rescan.bpel and the rest, check the namespace declarations at the top of each file and confirm what /client points to. The block above is right in the majority of cases; customized processes are where it is not, and that is exactly where a paste looks fine and behaves wrong.
While you are in there, swap AXF_CommentTypes.xsd for the newer file in every process; it lives under each process's xsd folder.
What the diff tool leaves behind
- New files that do not exist in your version have to be copied, not merged. The comparison marks files present on one side only: the
.designerand.taskeditordirectories, individual XSDs, and others that shipped in the newer baseline. Do the folder compare and copy every right-only file across. Missing a whole file is easier than missing a line and harder to diagnose. .bakand leftover artifacts accumulate. The merge tools leave backup files wherever changes were made. Clean them afterwards, or leave them until validation is done; they are a cheap way to revert a bad change.
Why this maps directly onto 12c to 14c
The version numbers above come from an 11g-era lineage, but the shape of the problem is exactly what a SOA Suite 12c to 14c upgrade throws at customized composites: schema references that need to resolve through the MDS, namespace bindings that do not survive a naive merge, and shared logic re-authored between releases. The platform upgrade moves the runtime. The BPEL processes are a separate, hands-on migration, and the parts that break are the parts you customized, which is the part no generic guide covers. Where the composites drive AP approval alongside BPM, the combined SOA and BPM upgrade is where this work sits in the wider plan.
If the SOA estate is heavily customized and thinly documented, this is the situation the work exists for: reading the running processes directly and carrying them to the new release without depending on documentation that may not exist. As always, validate against a non-production copy first; this is a field runbook, not a replacement for Oracle's upgrade documentation for your specific source and target.
Questions
Why do BPEL processes fail to compile after the SOA upgrade?
Usually because a schemaLocation still points at a file local to the project instead of the MDS. From 11.1.1.6 onward, shared schemas should resolve through oramds:///soa/shared/..., and a single missed local reference produces a compile failure that does not name it. Grep every process for schemaLocation= before deploying.
Why did the merge silently break a namespace binding?
The new baseline adds namespace declarations such as ns5 that assume the prefix is free. If a customization already claimed it, merging the line verbatim rebinds whichever side loses. Reconcile the xmlns declarations at the top of each .bpel file by hand; renumbering the incoming prefix is almost always less work.
Can I just take the new Transform_CopyCommentsToTask block?
Only after confirming what /client resolves to in your process. The new XSLT-based block replaces the old copyList, and it works in most cases, but a customized process may bind /client to something the reference does not expect. Check the namespace declarations before pasting it into each process.
Does the .adf directory matter?
Yes. It holds adf-config.xml with the MDS reference, it is a dot-directory at the top of the listing, and it is easy to miss on a folder compare. Copy it into the project or the oramds references cannot resolve.