Customization Archives in MAS Manage: Surviving the 7.6.x to MAS Migration
# Customization Archives in MAS Manage: Surviving the 7.6.x to MAS Migration
If you have ever lost a custom button, a bespoke escalation, or a heavily modified field class during a Maximo upgrade, you know that customizations are the most fragile part of any platform change. In MAS, the customization story has been rebuilt from the ground up. The old Maximo Archiving tool is no longer supported, and the replacement, customization archives, behaves differently in important ways.
This article walks through how customization archives actually work in MAS Manage, how to build one correctly, and how to validate it before you trust it with a production deployment. The goal is to make your customizations survive the next upgrade, not just the one you are running today.
What Changed and Why It Matters
In Maximo Asset Management 7.6.x, customizations were typically deployed in one of three ways:
1. Java class modifications placed in the application's classpath, often patched into the deployed EAR.
2. Database configuration changes delivered through XML files and applied with the Maximo Configuration Application.
3. Custom Java classes packaged as a Maximo Archive and applied through the Maximo Archiving tool.
Maximo Archiving was the most powerful of these because it could deliver custom Java classes, database scripts, and configuration XML in a single, signed archive. It was also the source of countless upgrade pain points, because archives were applied with database changes that sometimes conflicted with the base product upgrade.
In MAS Manage, Maximo Archiving is explicitly not supported. The replacement is the customization archive, which packages the same kinds of content but is applied through the Manage deployment process on OpenShift. The archive is built once, versioned with your code, and applied declaratively. The operator reads the archive, applies each component in the correct order, and tracks the result in the deployment history.
The practical effect is that customizations are now treated as part of the deployment, not as a separate concern. They live in version control, they are validated through the deployment pipeline, and they are applied consistently across environments. The discipline is closer to application development than to Maximo configuration, and that is the point.
How Customization Archives Are Structured
A customization archive is a directory or compressed file with a defined structure. The simplest valid archive looks like this:
code blockEach top-level directory is reserved for a specific content type:
- classes/ contains compiled Java classes that will be loaded by the Manage application server. The directory structure must match the Java package structure, with each package as a separate directory.
- database/ contains SQL scripts that will be executed against the Maximo database during deployment. The naming convention is Flyway-style, with a version prefix that determines the order of execution.
- scripts/ contains Jython or Groovy automation scripts that will be imported into the Manage script library. The scripts are imported as the raw source, and the Manage application compiles them at load time.
- xml/ contains Maximo configuration XML that will be applied through the Configuration Application. The XML format follows the standard Maximo configuration export schema.
The `manifest.json` is required and describes the archive's identity and dependencies:
code blockThe `dependsOn` field is critical. It ensures the archive is only applied to a Manage deployment at a compatible version, and it gives the operator the information it needs to refuse to apply the archive if the dependency is not satisfied. A version mismatch in `dependsOn` will block the deployment, which is the correct behavior: applying a customization archive to an incompatible base version is one of the surest ways to break an environment.
The `components` field is optional but recommended. It tells the operator what to expect in the archive, and it allows the operator to validate that the archive is complete before applying it. If you list a component in the manifest but it is missing from the archive, the operator will refuse to apply the archive and will report the missing component in the deployment logs.
Building a Customization Archive: A Worked Example
The most common scenario is migrating a 7.6.x customization to MAS. Let us walk through a realistic example.
Suppose your 7.6.x deployment had:
- A custom Java class `psdi.app.workorder.SetPriorityFromAsset` that ran on a work order save to copy the priority from the parent asset.
- A database view `WORKORDER_V` that joined work orders to their location hierarchy.
- An automation script `WO_AUTOFOLLOWUP` that created a follow-up work order when a corrective work order was closed.
In MAS, these three customizations become three components in one archive. The migration involves more than moving files, though. The API has changed in places that matter, and the database scripting model has been rebuilt.
Step 1: Compile the Java Class
Compile against the MAS Manage API rather than the 7.6.x API. The package names are similar, but the API has changed in places that matter, particularly around cron tasks, integration framework, and the MboSet lifecycle.
code blockPlace the compiled class under `classes/` in the archive, preserving the package path. The operator will load it into the Manage classpath at startup.
The MAS Manage API has several changes from 7.6.x that catch developers off guard:
- The `MboSet` lifecycle methods (`init`, `save`, `delete`) have been refactored in some object classes. If your customization depends on a specific save lifecycle, validate it against the new version.
- The integration framework now uses Kafka or another supported JMS provider instead of the SI bus. Custom code that depends on the SI bus will not work.
- The cron task API has been updated to support the new scheduling model. Custom cron tasks need to be refactored.
Step 2: Convert Database Changes to Migration Scripts
The database view becomes a SQL migration script. Name it with a version prefix to ensure idempotent application:
code blockUse a Flyway-style naming convention (`V001__`, `V002__`) so that scripts apply in the correct order and the operator can track which scripts have been applied. The operator maintains a `flyway_schema_history` table in the Maximo schema for this purpose.
For more complex migrations, use a proper migration tool like Flyway or Liquibase rather than hand-written SQL. Flyway supports repeatable migrations, baseline migrations, and out-of-order migrations, all of which are useful when you have a long history of database changes.
The most common mistake in database migration scripts is to assume an empty schema. A script that creates a table will fail if the table already exists. Use `CREATE OR REPLACE` for views and functions, and `IF NOT EXISTS` for tables. If you need to handle data migrations, use a separate script with a higher version number, and run it after the schema changes have been applied.
Step 3: Package the Automation Script
Export the automation script from the source environment as XML, place it in the `xml/` directory, and the operator will import it during deployment:
code blockIf your automation script uses libraries that are not present in the Manage base image, you have two options: include them as additional JAR files in the `classes/` directory, or refactor the script to use only the standard library. Including arbitrary JAR files is a security and maintenance risk, so refactor when you can.
A common gotcha is that automation scripts in MAS Manage are compiled at load time, not at deployment time. If your script has a syntax error, the Manage pod will fail to start, which is a more disruptive failure mode than the 7.6.x equivalent. Always validate the script syntax in a lower environment before deploying.
Step 4: Build the Archive
Once the structure is in place, package the directory into a compressed file. The operator will read the archive from a persistent volume or a container image, depending on your deployment pattern:
code blockA useful pattern is to include a build script that produces the archive from a source repository. The build script can run validation steps (Java compilation, SQL syntax check, script syntax check) before producing the archive, which gives you an early warning of any issues.
code blockValidating the Archive Before Production
Customization archives that fail in production are one of the most expensive failure modes in a MAS deployment. The fix is a validation routine that runs in a lower environment on every archive change.
A good validation routine tests four things:
1. Java classes load. Start a test Manage pod with the archive applied and check the application server logs for `ClassNotFoundException` or `NoClassDefFoundError`. Both are common when a class depends on another class that did not make it into the archive.
2. Database scripts apply cleanly. Run the archive against a copy of the production database schema. Watch for failed constraints, missing references, or scripts that cannot be replayed.
3. Automation scripts compile. The Manage application compiles automation scripts at load time. A syntax error in a script will block pod startup, so verify before you deploy.
4. XML configuration applies. The Configuration Application runs in dry-run mode during the archive application, so most XML issues surface as warnings rather than failures. Promote warnings to errors in your test environment so you do not ignore them.
The community-published `mxvalidator` tool automates much of this. It is worth integrating into your CI/CD pipeline so that every archive change is validated before it can be promoted to the next environment.
A useful pre-flight checklist for archive validation:
| Check | Tool | Pass Condition |
|-------|------|----------------|
| Manifest schema | JSON schema validator | Valid against the customization archive schema |
| Java classes compile | `javac` | No errors, no missing dependencies |
| Java classes load | Application server log | No `ClassNotFoundException` |
| Database scripts replay | Migration tool | No errors, no missing references |
| Automation scripts parse | Manage script compiler | No syntax errors |
| XML applies | Configuration Application | All changes applied or explicitly skipped |
Common Pitfalls and How to Avoid Them
Forgetting to Update the Classpath
Some custom Java classes depend on libraries that were present in the 7.6.x WebSphere deployment but are not in the MAS Manage base image. The most common culprits are:
- Apache Commons libraries at non-standard versions.
- JDBC drivers for non-Db2 databases.
- Internal IBM libraries that were available in WebSphere.
If your custom class imports a symbol that does not resolve, the Manage pod will fail to start. Always validate in a clean environment, and use a tool like `jdeps` to identify external dependencies before deployment.
Database Scripts That Assume an Empty Schema
A SQL script that creates a table will fail if the table already exists. Use `CREATE OR REPLAC
...