Structuring Custom Workflow Extensions in Windchill Service Management
Modular Package Architecture
Consolidate all service-mgmt workflow extensions under a single top-level site customization package (e.g., ext.servicemgmt.workflows) rather than mixing embedded customization-layer code with separate extension packages. Use sub-packages to separate concerns:
ext.servicemgmt.workflows/
├── delegates/ # WfDelegate implementations
├── expressions/ # Workflow condition/expression classes
├── notifications/ # Event-driven notification handlers
├── utils/ # Shared service locators, constants
└── tests/ # JUnit test classes
This keeps WT_HOME/codebase modifications minimal and contained. All custom logic references the sub-package utilities rather than duplicating helper code per workflow template.
Workflow Template Management
Store workflow templates as exportable .wft files under source control. Export via Windchill Export Utility or windchillDS CLI (verify in your version). Never hand-edit .wft XML directly in production — treat templates as build artifacts regenerated from version-controlled source.
Delegate Pattern (Java — server-side)
Use com.ptc.windchill.wf.delegates.WfDelegate for business logic rather than embedding logic in workflow template expressions:
package ext.servicemgmt.workflows.delegates;
import com.ptc.windchill.wf.WfContext;
import com.ptc.windchill.wf.delegates.StandardWfDelegate;
import wt.part.WTPart; // substitute with your domain object
public class EquipmentServiceDelegate extends StandardWfDelegate {
@Override
public void doActivity(WfContext context) throws Exception {
// Retrieve workflow variables safely
String equipmentId = (String) context.getValue("equipmentId");
String serviceType = (String) context.getValue("serviceType");
// Business logic isolated here — no workflow template coupling
ServiceAssignmentService.assignTechnician(equipmentId, serviceType);
// Set output variable for downstream routing
context.setValue("assignmentStatus", "ASSIGNED");
}
}
Debug Approach
- Enable workflow debug logging via
wt.log configuration: set com.ptc.windchill.wf to DEBUG (verify property path in your version).
- Use Process Monitor (
wt/WorkflowAdmin) to inspect suspended process instances and variable state at runtime.
- For delegate exceptions, check
MethodServer logs first — stack traces from delegate failures typically surface there before the UI error.
- Reproduce issues in a cloned workflow template against a non-production wt.home before touching any shared template.
Rollback Strategy
- Maintain versioned
.wft exports per sprint. Rollback = re-import the prior version via Workflow Template Administration.
- Java delegate changes: keep prior JAR archived; redeployment is a
windchill stop/start cycle — plan a maintenance window.
- Never modify baseline PTC workflow templates directly; always copy-then-modify to preserve rollback path.
Testing
Write JUnit tests against delegate classes in isolation using mock WfContext implementations. Avoid testing workflows solely through UI integration tests — they’re brittle and slow. Validate routing logic with condition expression unit tests before promoting templates.
Documentation Standard
Embed a structured header block in every delegate class (author, associated template name, workflow variables consumed/produced, PTC KB references). This is the single most impactful maintainability practice at scale — workflow variables are invisible at the template layer without it.
This draft is based on general Windchill knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.