The AWS SDK v1 to v2 Migration in Maximo Manage: A Code-Level Readiness Playbook

The removal of AWS SDK for Java v1 JARs from Maximo Manage means custom code importing the com.amazonaws package will fail once the relevant fix pack is installed. This playbook gives teams a concrete inventory, triage, and remediation process for finding every affected artifact, including…

Share

The AWS SDK v1 to v2 Migration in Maximo Manage: A Code-Level Readiness Playbook

Maximo Manage used AWS SDK for Java v1.x for Amazon S3, IBM Cloud Object Storage, and other S3-compatible storage targets. Amazon ended v1.x support on December 31, 2025. Manage has migrated to the v2 SDK, and the three v1 JARs are removed from the distribution. IBM states the consequence without hedging: any custom code containing imports from the com.amazonaws package will fail to compile or run once the fix pack is installed unless it is updated to the v2 SDK.

This is a code-breaking change shipped inside an ordinary patch release, and it is landing on the lines most teams will target during the current migration wave. The removal is delivered in Maximo 9.0.29, 9.1.21, 9.2.2, and the 9.3 September feature channel. A Maximo-line patch shipped on September 24, 2026 on the 9.1 train confirms that the delivery pipeline carrying this change is active and arriving now.

The risk profile is unusual and worth naming before the process. Most upgrade breakages are functional: something behaves differently, and testing finds it. This one is structural. Code that referenced the old classes no longer has those classes, so the failure is a compile error for compiled extensions and a runtime error for interpreted or reflective paths. That distinction matters because compiled extensions fail loudly at build time, which is good, while automation scripts and dynamically loaded utilities can fail at the moment of execution, which is bad. A script that only runs during the fiscal close, or only on a specific integration channel, will not reveal itself in a smoke test.

This article is a playbook. It covers how to inventory every affected artifact, how to triage by failure mode rather than by file type, how to remediate the common patterns with the v2 equivalents, and how to sequence the work so the migration to v2 happens before the patch that removes v1, not after. It is written for Maximo developers, integration engineers, and upgrade leads who need to produce a readiness assessment this quarter, and for the managers who need to understand why this cannot be handled as a routine patch-testing item.

One scope note up front. This playbook addresses custom code and third-party add-ons that reference the AWS SDK directly. It does not address the product's internal use of the SDK, which IBM has already migrated, nor does it treat storage configuration changes that do not involve the SDK at all. The affected population is code you or your vendors wrote or shipped.

Why This Breakage Is Different From a Normal Patch Risk

Start with the mechanical facts, because they determine everything downstream. The three removed JARs are aws-java-sdk-s3, aws-java-sdk-core, and aws-java-sdk-kms. The first carried the AmazonS3 interface, the AmazonS3Client implementation, and the S3 model classes. The second carried BasicAWSCredentials, ClientConfiguration, and the signing infrastructure. The third carried the v1 KMS client. Their replacements are sdk-core, aws-core, s3, and kms from the software.amazon.awssdk group, version 2.41.34. The v2 S3 surface offers S3Client and S3AsyncClient rather than a single synchronous client interface.

Now consider what happens at the boundary. Compiled code with an import statement referencing the old package fails at build time. That is the easy case: the build breaks, a developer sees it immediately, and remediation is straightforward, if tedious. Interpreted paths behave differently. Automation scripts in Maximo are not compiled against the JARs; they resolve classes at execution time. A script that constructs a client through a fully qualified class name will resolve that name when the script runs, not when it is saved. If the script executes weekly, or on a specific event, the failure appears weeks after cutover, in production, on a path that may not have been exercised in testing.

Reflective and dynamically loaded code has the same property. So do standalone utilities shipped alongside the application that are launched ad hoc rather than as part of a scheduled pipeline. So do third-party add-ons that were compiled against the v1 JARs and are now loading into a runtime where those JARs are absent. These fail with class-not-found errors, and they fail at the worst possible moment, which is when someone needs them.

There is a second dimension that makes this breakage unusual: the failure can be silent in a different sense. A script that catches exceptions broadly may log a warning and continue, producing a partial result that looks like success. An integration that writes to S3 may fail to write while its transaction elsewhere commits, creating data inconsistency rather than an obvious error. For any code path that touches object storage for archival, attachment handling, report output, or backup, the risk is not just a crash. It is a divergence between what the system believes happened and what actually happened.

The third dimension is vendor coupling. If a third-party solution references the v1 package, the fix is not in your hands. You need the vendor to release a v2-compatible version, and you need to know when. Industry solutions and add-ons must be upgraded in lockstep with the platform, which means your readiness gate depends on external parties whose release schedules you do not control. Discovering this dependency late is the single most common way a migration plan slips.

The combination of these three properties is why this item cannot be folded into routine patch testing. Routine testing validates behavior under representative use. This change requires a static inventory of code references, an analysis of when each path executes, and a dependency check on third-party components. That is a different exercise, and it should be scheduled as one.

Building the Inventory: Finding Every Affected Artifact

The inventory is the foundation of the whole effort, and it must be exhaustive rather than representative. Six artifact classes should be swept.

The first is custom Java extensions and compiled classes. Search the source tree and any build artifacts for imports from the com.amazonaws package. Include test code, because a failing test build blocks the pipeline even if production code is clean. Record, per artifact, which SDK capabilities it uses: S3 object operations, credential construction, client configuration, signing, or KMS. The capability list drives remediation effort, since credential and configuration patterns changed more than simple object operations.

The second class is automation scripts. These require a different search because they do not contain import statements. Search for fully qualified class names appearing as string literals or in binding contexts, and search for any script that references S3, object storage, credentials, or signing. The search terms should include the class names directly: AmazonS3, AmazonS3Client, BasicAWSCredentials, ClientConfiguration, and the KMS v1 type names. A script can reference these through a variable assignment, a method call, or a reflection path, so the search should be broad and the results reviewed by someone who knows the codebase.

The third class is standalone utilities and integration components packaged with MAS. These include command-line tools, scheduled jobs, and helper programs that ship alongside the application. They are often maintained by a different team than the core customizations, which is exactly why they get missed. Inventory them by deployment location rather than by repository, to catch anything that was placed on the server without living in the main source tree.

The fourth class is third-party and industry solutions. For each add-on, determine whether it references the v1 package and whether the vendor has a v2-compatible release. Document the vendor, the version in use, the required version, and the vendor's stated timeline. If a vendor cannot confirm a timeline, that is a risk item, not an open question, and it belongs in the plan with an owner.

The fifth class is configuration and environment assets that are not code but still depend on the SDK. Credential configuration files, endpoint settings, region settings, and any custom signing or encryption configuration fall here. The v2 SDK reads configuration through a different precedence chain than v1, so a working v1 configuration is not guaranteed to be a working v2 configuration. Review each one and validate it in a test environment.

The sixth class, often overlooked, is documentation and runbooks. If a runbook instructs an operator to run a utility that depends on the removed JARs, the runbook is now wrong. Updating operational documentation is part of the change, not an afterthought, and the update should happen in the same change window as the code fix.

The inventory output should be a single register with, per artifact: owner, artifact type, SDK capabilities used, execution trigger, frequency, criticality, disposition, and remediation owner. Criticality should reflect when the artifact runs. A script that runs during a nightly close is higher criticality than one that runs on a manual, occasional path, even if both touch S3, because the nightly path has less tolerance for a delay.

Two process notes improve inventory quality. First, do the sweep while the estate is still on the pre-patch state, because that is when the original code and its runtime behavior are observable. Reconstructing an inventory from a half-migrated environment is slower and less reliable. Second, have a second person review the script results, because script search results are noisy and a missed script is exactly the kind of gap that only surfaces in production.

Triage: Classifying by Failure Mode and Sequencing

Once the register exists, triage by failure mode rather than by artifact type. Three tiers emerge naturally.

Tier one is build-blocking artifacts. These are compiled classes that will not compile against the new JAR set. They are the safest category because they announce themselves, but they are also on the critical path for any build pipeline, so they should be remediated first. A clean build is a prerequisite for everything else, including testing the remediation itself.

Tier two is execution-time artifacts. These are automation scripts, reflective paths, standalone utilities, and dynamically loaded components that will fail when they run rather than when they are built. Within tier two, order by execution frequency and business criticality. A daily integration path that fails is a same-day incident; a quarterly archival job that fails is a discovery three months out. Remediate the frequent, critical paths first, and then work down to the rare paths, ensuring that nothing is left unaddressed simply because it runs infrequently.

Tier three is externally dependent artifacts. These are third-party components whose fix must come from a vendor. Triage these by dependency risk: is the vendor responsive, is a compatible release available, and does the component's execution path matter during the migration window? For any component where the vendor timeline is unknown, plan a mitigation. Mitigation can be a temporary replacement path, a deferral of the component's function, or an explicit accepted risk with a signed record, but it cannot be an unanswered email.

Sequencing across tiers follows a simple rule. Build-blocking work first, because it gates everything. High-frequency execution-time work second, because it protects operational continuity. Vendor-dependent work in parallel from day one, because it has the longest and least controllable lead time. Low-frequency execution-time work third, bundled into the same change window where practical. Documentation and runbook updates in the same window as the code they describe.

Two scheduling constraints deserve emphasis. First, the v2 migration must be validated in a test environment that mirrors the target patch level, because the point of the exercise is to be ready before the fix pack lands, not after. Second, the migration of custom code to the v2 SDK does not require waiting for the platform patch. The v2 JARs are available, so the code work can and should begin before the patch is applied. Doing this in the right order turns a potential production breakage into a planned code change.

For teams that are already mid-migration to MAS, there is a useful consolidation opportunity. The v2 SDK migration touches the same code that a MAS migration touches. Doing them as one change, with a single inventory and a single test cycle, is cheaper than doing them as two. The failure mode to avoid is treating the SDK work as a small add-on to a platform migration and discovering, during cutover, that the small add-on has its own dependency chain.

Remediation Patterns: What Actually Changes in the Code

The v1 to v2 migration is not a mechanical rename, though many of the differences are mechanical. Four patterns cover most of the work.

The first is client construction. In v1, code typically built a client through a builder that took a ClientConfiguration object and credentials. In v2, clients are built through builders on the specific client type, configuration is handled through an override mechanism, and credential providers are a distinct abstraction. The shape of the change is straightforward but not cosmetic: a developer needs to decide whether the client is synchronous or asynchronous, how credentials are supplied, and whether any shared configuration should be applied programmatically or through the environment.

The second pattern is credentials. In v1, BasicAWSCredentials was the common explicit construction and ClientConfiguration carried much of the tuning. In v2, the credential provider mechanism is more structured, and the recommended path is to supply a provider rather than static credentials. This is a good opportunity to remove hardcoded or file-embedded credentials from custom code entirely, replacing them with a provider backed by the platform's secret handling. For organizations with security review requirements, this is a favorable side effect worth documenting: the migration is an occasion to improve credential hygiene, not just to restore function.

The third pattern is the S3 interaction surface itself. In v1, a single synchronous client type handled the common operations. In v2, the client types are separate, and the request and response objects are constructed differently. Object operations that read, write, list, or delete map cleanly, but the code around them changes: request builders, response handling, and error semantics all differ. The error model is worth attention, because v2 exceptions are typed differently, and code that catches a broad exception type in v1 may not catch the equivalent v2 failure. Any remediation that touches error handling should be tested against failure conditions deliberately, not just against the happy path.

The fourth pattern is KMS usage. Code that used the v1 KMS client for encryption operations must move to the v2 client. Encryption paths are usually low-frequency and high-consequence, which makes them a classic tier-two artifact that hides until it is needed. Test these explicitly with representative data.

Beyond the four patterns, general guidance applies. Use the v2 default configuration where possible rather than reproducing every v1 tuning value, because the v2 defaults reflect current best practice and over-specifying configuration is a common source of subtle behavioral differences. Validate region and endpoint behavior explicitly, especially for S3-compatible stores that are not AWS S3, since compatibility layers can vary in which API features they support. And add a test that executes each remediated path at least once in an integration environment, because a compile-clean change is not a runtime-validated change.

Two anti-patterns to avoid. The first is a shim layer that recreates the v1 class names as wrappers over the v2 SDK. This can buy time, but it hides the migration debt and creates a component that will need its own lifecycle management. If a shim is used as a temporary measure, it should have an expiry date and an owner. The second is remediating code without updating the tests that cover it, which produces a false sense of validation and lets regressions pass unobserved.

Making It a Gate, Not a Scramble

The difference between a manageable migration and a scramble is whether the v2 readiness work is a gate in the migration plan or a discovery inside it. Three practices convert this item into a gate.

First, add a v2 reference check to the definition of ready for any migration milestone. Before an environment is promoted past a given stage, the inventory must be complete and every tier-one and tier-two artifact must be remediated or explicitly disposed. A gate does not need to be elaborate; it needs to be enforced, and it needs a named owner who can say no.

Second, tie the vendor dependency to a date. For each third-party component, record the vendor, the needed version, and the commitment date. Review those dates on a fixed cadence, and escalate slips early. Vendor-dependent items have the longest lead time and the least controllability, so they benefit most from early tracking.

Third, rehearse the failure, not just the success. Deliberately run the remediated paths under conditions that would have failed with v1: a missing credential, an unreachable endpoint, an invalid object key. The purpose is to confirm that error handling and logging behave correctly, so that a future failure produces a diagnosable message rather than an ambiguous warning. Given that this change can fail silently, observability is part of the remediation, not an extra.

There is also a governance dimension. A migration plan that lists "upgrade platform" without listing the code remediation beneath it is understating the work. The v1 SDK removal is a named, dated, vendor-documented change with a known affected population. Recording it in the plan as a distinct workstream, with its own inventory and gate, gives stakeholders an accurate picture and gives the delivery team a defensible basis for the schedule.

Finally, note the compounding effect of timing. The removal arrives on the 9.x lines that most migrations target. The Maximo-line patch activity inside the current deadline week shows the pipeline is live. The practical conclusion is that the v2 migration is not a future concern; it is a current one, and teams that start the inventory now will meet it as a planned change while teams that wait will meet it as an incident.

Practical Implications

Treat the v2 SDK removal as a scheduled code change with a hard dependency on a patch you intend to install, not as an upgrade risk to be discovered. The inventory is the deliverable that makes this possible, and it must include automation scripts and third-party components, because those are where the silent failures live.

Budget for the vendor dimension explicitly. Third-party remediation is the longest-lead, least-controllable part of the work, so it needs to start first and be tracked against dates rather than intentions.

Sequence by failure mode. Build-blocking code first because it gates the pipeline, high-frequency scripts next because they protect operations, vendor dependencies in parallel from the start, and low-frequency paths bundled into the same change windows.

Validate in a test environment at the target patch level. A compile-clean artifact is not a runtime-validated artifact, and the failure mode here is execution-time, so testing must exercise the paths, including their error handling.

Consolidate where the opportunity exists. Teams already migrating to MAS can fold the SDK remediation into the platform change, sharing one inventory and one test cycle, provided the work is scoped as its own workstream with its own gate rather than as a footnote.

Bottom Line

Maximo Manage has moved from AWS SDK for Java v1 to v2, and the v1 JARs are removed. Custom code that imports the old package will not compile or run once the fix pack lands, and the fix pack is arriving on the lines most teams are targeting during the current migration push.

The affected population is broader than the obvious compiled extensions. Automation scripts, standalone utilities, reflective code paths, and third-party add-ons can all fail at execution time, which means the failure can surface weeks after cutover on a path that testing never exercised. That property, more than the removal itself, is what makes this a readiness exercise rather than a patch-testing line item.

The process is not complicated. Inventory every artifact by reference, not by file type. Triage by failure mode and frequency. Remediate the four common patterns, using the change as an occasion to improve credential handling. Track vendor dependencies against dates. Make v2 readiness a gate in the migration plan. Teams that do this will experience the v2 change as a planned code migration. Teams that do not will experience it as a production incident discovered by a script that ran for the first time after the patch.

Read more