How Maximo Java Extensions Actually Work: The Four-File MBO Pattern

Part 1 of the MAS JAVA EXTENSIONS series. Before any add-on, any chain, or any super call makes sense, you need a precise mental model of how a single extension is built. This is that model.

<aside>
🎯 Who this is for: Maximo developers who write custom Java, technical architects planning which add-ons can coexist, and upgrade and troubleshooting leads who need to reason about extension behavior instead of guessing at it.
</aside>

Estimated read time: 20 minutes

The Question Every Maximo Developer Eventually Asks

You have written a customization on the Asset object. You extended AssetSet, dropped in your logic, rebuilt, and deployed. Then something upstream fired that you did not write — a validation you never coded, a default you did not set — and you found yourself staring at a stack trace full of class names with a Plus in the middle of them, wondering: which class is actually running here?

That confusion is not a knowledge gap in you. It is a gap in the documentation. The Java extension architecture that lets IBM's add-ons and industry solutions layer onto core Maximo is almost never explained in one place. But it is not magic, and it is not complicated once you see the shape of it. Every add-on — Transportation, HSE, Spatial, Nuclear, and the rest — extends the core through the same standardized mechanism, using a unique PLUS letter prefix.

And the entire mechanism is built on one small, repeating unit: the four Java files behind every Maximo Business Object. Understand those four files and how one set inherits from another, and the whole extension story — chains, super behavior, upgrade surprises — becomes readable. This post is about getting that foundation exactly right.

Key insight: Maximo layers product functionality through plain Java class inheritance. There is no proprietary sorcery here — just classes extending classes and interfaces extending interfaces, following a naming convention strict enough that six industry solutions can stack on one object without colliding.

The MBO Architecture: Four Files, Every Time

Every Maximo Business Object (MBO) comprises four Java files. Not one, not two — four. Each has a distinct job, and each extends a specific framework base class. Here is the pattern in full:

File — Purpose — Base Class

MBO Class — Business logic for a single record — Extends psdi.mbo.Mbo

MBO Set Class — Logic for a set of records (the whole table) — Extends psdi.mbo.MboSet

MBO Remote Interface — Remote access contract for MBO — Extends psdi.mbo.MboRemote

MBO Set Remote Interface — Remote access contract for MBO Set — Extends psdi.mbo.MboSetRemote

Read that table slowly, because it is the Rosetta Stone for everything that follows. Two of the four files are classes (the ones that hold your actual logic), and two are Remote interfaces (the contract for remote access). The classes carry the behavior; the interfaces define the boundary.

To make it concrete, look at the core Asset object — the one you have almost certainly customized at some point. Its four files live in the psdi.app.asset package:

psdi.app.asset.Asset                 (MBO class)
psdi.app.asset.AssetSet              (MBO Set class)
psdi.app.asset.AssetRemote           (MBO Remote interface)
psdi.app.asset.AssetSetRemote        (MBO Set Remote interface)

Asset is where the business logic for a single asset record lives. AssetSet is the logic for a set of asset records — think of it as the class that governs the whole ASSET table. AssetRemote and AssetSetRemote are the Remote interfaces that let other parts of Maximo talk to those objects across the remote boundary.

That is the four-file pattern. Every object you can name — WORKORDER, LOCATIONS, ITEM, PM, JOBPLAN — has the same quartet behind it. Learn it once, and you have learned it for all of them.

How Maximo Picks the Class: MAXOBJECT.CLASSNAME

So you have four files. When a user opens the Assets application or a script queries assets, how does Maximo know which class to instantiate?

Through a single column in the database.

The MAXOBJECT table links each Maximo object to its MBO Set class via `MAXOBJECT.CLASSNAME`. For the ASSET object, that value is:

psdi.app.asset.AssetSet

That is it. The object definition points at the set class — AssetSet, not Asset — because Maximo instantiates a set and then materializes individual MBOs from it. When you ask Maximo for asset records, it reads MAXOBJECT.CLASSNAME for ASSET, finds psdi.app.asset.AssetSet, and instantiates that.

This one column is why the question at the top of this post has an answer at all. In a plain, un-extended Maximo, MAXOBJECT.CLASSNAME for ASSET is psdi.app.asset.AssetSet, and that is exactly the class that runs. The moment an add-on enters the picture, that value changes — and the class registered there is no longer the core set class. That is the thread we pick up next.

How Extensions Layer On Top

Here is where the PLUS convention earns its keep.

When an add-on extends a core object, it does not modify the core files. It creates four new files — mirroring the original quartet — following the PLUS convention. Each new file inherits from its core counterpart.

Take the canonical example: Transportation (prefix PLUST) extending Asset. The add-on ships these four files in the psdi.plust.app.asset package:

// Package: psdi.plust.app.asset

public interface PlusTAssetRemote extends AssetRemote { ... }
public interface PlusTAssetSetRemote extends AssetSetRemote { ... }
public class PlusTAsset extends Asset implements PlusTAssetRemote { ... }
public class PlusTAssetSet extends AssetSet implements PlusTAssetSetRemote { ... }

Look at what each line is doing:

  • PlusTAsset extends Asset — the Transportation MBO class inherits every method of the core Asset MBO class, then adds or overrides what Transportation needs.
  • PlusTAssetSet extends AssetSet — same relationship, one level up, for the set.
  • PlusTAsset implements PlusTAssetRemote, and PlusTAssetSet implements PlusTAssetSetRemote — each class fulfills its own Remote contract.
  • PlusTAssetRemote extends AssetRemote, and PlusTAssetSetRemote extends AssetSetRemote — the interfaces inherit the core interfaces so the extended object still satisfies every contract the core object did.

The symmetry is the whole point. The class side and the interface side both inherit in parallel, so a PlusTAsset is-an Asset in every sense the JVM cares about, while carrying Transportation's additions on top.

The rules that govern this are worth stating explicitly, because every well-formed PLUS extension obeys all of them:

Key rules:

  • The MBO class extends the core MBO class.
  • The MBO Set class extends the core MBO Set class.
  • Each implements its own Remote interface.
  • The Remote interface extends the core Remote interface.
  • Package naming follows the pattern psdi.plusX.app.{module}.PlusX{ObjectName}.

That last rule is doing quiet, heavy lifting. The prefix letter (T for Transportation) shows up in both the package (psdi.plust.app.asset) and the class name (PlusTAsset). Because every add-on gets its own letter, its classes can never collide with core Maximo or with another add-on's classes — even when two of them extend the very same object. That uniformity is what makes stacking add-ons possible at all.

Key insight: A PLUS extension never edits the core. It creates a parallel four-file set that inherits from the core four, and the prefix guarantees the new classes have unique, non-colliding names. This is why the class registered in MAXOBJECT.CLASSNAME for an extended object is the extension's set class, not the core one — and why a super.save() from that extension flows down into the core logic underneath.

And that is the connective tissue back to the previous section. Once Transportation is installed and extending Asset, MAXOBJECT.CLASSNAME no longer points at psdi.app.asset.AssetSet alone — the top of the resulting chain becomes what Maximo instantiates. How that chain is ordered when multiple add-ons pile onto one object is the subject of Part 2. For now, the takeaway is simpler and more important: the extension is nothing more exotic than four files inheriting from four files.

Field Validation Classes: The Same Pattern, One Level Down

MBOs are not the only thing add-ons extend. Field validation classes follow the exact same inheritance model — and they are a common source of "where did that validation come from?" confusion, so they are worth understanding precisely.

A field validation class governs the behavior of a single attribute: what is allowed, what defaults, what fires when the value changes. Core Maximo ships these as Fld... classes. Add-ons extend them the same way they extend MBOs.

Here is Transportation extending the field validation class for the Asset item number:

// Core field validation
psdi.app.asset.FldAssetItemnum

// Transportation extension of that field validation
psdi.plust.app.asset.PlusTFldAssetItemnum extends FldAssetItemnum

Same shape you already know: the extension class (PlusTFldAssetItemnum) extends the core class (FldAssetItemnum), lives in the prefixed package (psdi.plust.app.asset), and carries the PlusT name prefix. If you have internalized the MBO pattern, you already understand field validation extension — it is the same idea applied to a field-level class instead of an object-level one.

The one new wrinkle is how the extension is declared. An MBO set class gets registered through MAXOBJECT.CLASSNAME, but a field validation extension is declared to Maximo in the `product.xml` file using the `<field>` tag. That is the mechanism that tells Maximo "for this attribute, use my extended validation class instead of the core one."

We are not going to unpack the full anatomy of product.xml here — that is Part 3's job, and it deserves the room. What matters at this stage is the connection: field validation extensions are declared with <field> in product.xml, just as service, MBO, and bean registrations have their own tags in the same file. The product.xml is the control file that ties all of these Java declarations back to a running Maximo.

Why This Uniform Pattern Matters

Step back and look at what you now hold.

Every Maximo object is four Java files with fixed base classes. Every add-on extends an object by creating four parallel files that inherit from those four, under a unique prefixed package. Field validation is the same relationship one level down, declared through product.xml. There is exactly one pattern here, repeated at two scales.

That uniformity is not an accident — it is the enabling design decision. Because every add-on follows the identical convention, IBM can let Transportation, HSE, Spatial, and a half-dozen industry solutions all extend the same core object, and the classes will never fight over a name. Each one slots into a predictable place in a predictable package. When you can look at a class name like PlusTAssetSet and immediately read it as "Transportation's extension of the core Asset set class," you are no longer customizing blind. You are reading the architecture.

That is the skill this series builds, one layer at a time. This post gave you the atom: four files, inheriting from four files. Part 2 assembles those atoms into the full PLUS registry — every prefix, what it means, and how Maximo orders multiple extensions on a single object into one inheritance chain.

Key Takeaways

  • Every Maximo Business Object is four Java files: an MBO class (extends psdi.mbo.Mbo), an MBO Set class (extends psdi.mbo.MboSet), an MBO Remote interface (extends psdi.mbo.MboRemote), and an MBO Set Remote interface (extends psdi.mbo.MboSetRemote).
  • The core Asset object is Asset, AssetSet, AssetRemote, and AssetSetRemote in the psdi.app.asset package.
  • `MAXOBJECT.CLASSNAME` is the single column that links a Maximo object to its MBO Set class — psdi.app.asset.AssetSet for the ASSET object.
  • A PLUS add-on extends a core object by creating four parallel files that inherit from the core four: PlusTAsset extends Asset, PlusTAssetSet extends AssetSet, with matching Remote interfaces, all under psdi.plust.app.asset.
  • Field validation classes are extended the same way (PlusTFldAssetItemnum extends FldAssetItemnum) and declared in product.xml with the <field> tag.

References

Series Navigation

Previous:Series Index

Next:Part 2 — The PLUS Registry and the MBO Inheritance Chain

Published by TheMaximoGuys | July 2026