IBM Maximo Real Estate and Facilities · Class Loader · A guide for Maximo people

The MREF Class Loader: your own code and pages, without rebuilding anything

Sooner or later someone asks for something MREF does not do out of the box: a custom page, a small integration, a 3D view of the portfolio. In Maximo you would reach for a customization archive and a rebuild. In Maximo Real Estate and Facilities (MREF) you upload a file into a record called a Class Loader, and the running system picks it up. This guide explains how that works, on a real example we built: MREF3D, a 3D globe of every building. It ends with MREF's built-in 3D feature, the BIM model viewer, so you know which one to use when.

What you will learn

Reading time: about 15 minutes. Companion guides: your first MREF app and the Admin Console, page by page.

In Maximo terms · the translation table
In MaximoIn MREF
Customization archive (a zip of classes, built into the image)Class Loader record with Java resource files, loaded while the system runs
Rebuild and redeploy the EAR / the Manage imageUpload a new file and save the record
Automation script (code stored in the database)The same idea, but compiled Java in a jar
A custom servlet or a custom REST handlerA class that implements IConnect, reached at /rest/<name>
A custom JSP or static files in maximouiwebA Web resource file (a zip), reached at /rest/<name>/resource/…
BIM viewer add-on for Maximo (Forge viewer)The 3D Model tab, built in, using Autodesk Platform Services

Part 1What a Class Loader is

A Class Loader is a record in MREF that holds files the application server should load in addition to its own. There are two kinds of file:

The name comes from Java: a class loader is the part of Java that finds and loads code. Each Class Loader record gets its own, so your jar does not mix with MREF's jars or with another extension's.

Uploadjar or zip, in the record Databasethe file is stored as a blob First useunpacked to the server disk Loadedown Java class loader Served/rest/<name> for signed-in users

Part 2The Class Loader list

Open Tools › System Setup › System › Class Loader. You need an administrator's access.

The Class Loader list on our system: 16 that came with the system, and MREF3D, the one we added.

Most of the list is IBM's own. It is worth reading, because it shows what Class Loaders are used for:

Class LoaderWhat it is for
EsriJS, ArcGIS, EsriIndoorMaps…The GIS maps: Esri's JavaScript pages (Web) and the code that feeds them (Java).
PortalCustom gauges on home pages.
EnergyStar, TBIConnector, AdlibConnectors to outside services: energy ratings, building insights, document compilation.
Integration, UXIntegrationTool, DsFieldMetaImportAdmin utilities.
ManageIntegration, MASCoreThe link to Maximo Manage and to the MAS suite: custom workflow tasks that call them.
TjeneConnectV2 / V3A third-party reporting extension.
MREF3DOurs: the Portfolio 3D page and its live data.
Key idea

IBM extends MREF with the same mechanism you will use. A Class Loader is not a hack; it is the supported way to add code and pages.

Part 3Inside one record: MREF3D

Class Loader MREF3D: Parent First, revision 13, and two resource files: the web zip and the jar.
FieldWhat it means
NameThe identity of the extension. It is part of every URL, and for a web service it must match the Java class name. Choose it once; do not rename.
ClassLoader TypeParent First: Java looks in MREF's own libraries first, then in your jar. Parent Last: your jar first. Keep Parent First unless you ship a library in a different version from MREF's.
Development ModeWhen ticked, MREF reloads your classes on every call. Handy while developing, slow in production. Leave it off.
RevisionGoes up each time the record is saved. Ours is at 13: thirteen uploads while we built it.
Resource FilesThe files themselves. Each one is its own small record with a type (Java or Web) and the uploaded file.

MREF3D holds two resource files: MREF3D (the Web zip with the page) and MREF3D.jar (the Java class). One Class Loader can hold both kinds, and that is the normal design: the page and the code it calls travel together.

Part 4Where the files live

This is the part that surprises people. The uploaded file is stored in the database, as a blob. The copy on the application server's disk is only a cache: MREF unpacks it from the database the first time the Class Loader is used.

/home/wiotp/userfiles/ClassLoader/
├── EsriJS/
│   ├── Java/   EsriJS.jar, TRIRIGAIntegration.jar
│   └── Web/    EsriJS_arcgis.js, language files, …
├── MREF3D/
│   ├── Java/   MREF3D.jar
│   └── Web/    index.html, app.js, config.json, sample.json, enrich.json
└── TjeneConnectV3/

That is the real folder on our application server pod. Notice two things. The list has 17 Class Loaders, but only three folders exist: the ones somebody has used since the pod started. And the split is always the same: Java/ for jars, Web/ for the unpacked zip.

In Maximo terms

In MAS, pods are replaceable: anything written on a pod's disk is lost when it restarts. Maximo Manage solves that by baking customizations into the image at build time. MREF solves it by keeping the files in the database and unpacking them again on demand. The result for you: a Class Loader survives restarts, upgrades of the pod, and a database backup and restore carries it to another system.

Trap · do not edit the files on disk

A change made directly in userfiles/ClassLoader works for a while, then disappears: MREF writes the database copy over it. Always change the resource file in the record.

Part 5The two URLs

Every Class Loader answers on two addresses, both under /html/en/default/rest/:

URLWhat answersFor MREF3D
/rest/<Name>/resource/<file>A file from the Web zip/rest/MREF3D/resource/index.html
/rest/<Name>The Java class com.tririga.custom.<Name>/rest/MREF3D?building=10336477

Both are served only to a signed-in user. Open either one without a session and MREF sends you to the login page. That is why a page delivered this way can call MREF's own data services with the viewer's session, and each person sees only what their security groups allow.

Part 6The web part: Portfolio 3D

The Web zip contains an ordinary web page: index.html, app.js and a few data files. It draws every building that has a latitude and longitude on an Esri 3D globe.

Portfolio 3D, served from the MREF3D Class Loader: 184 buildings, 72 floors, 9,458 rooms. Bottom right: "Live from MREF".

The data is not copied into the page. The page asks MREF for it, with the same data sources the built-in Locate Map application uses: one for buildings with their coordinates, one for rooms with their floor and capacity. If that request is refused, the page falls back to a snapshot file and says so in amber, so nobody mistakes old data for live data.

Charlotte Watson Center: one block per floor, coloured by rooms per floor, with leases, capital projects, maintenance, energy and costs on the right.

Pick a building and the page flies to it. The building is drawn as a stack of floors, coloured by the number of rooms or the capacity of each floor. The panel on the right lists the floors (6 floors, 894 rooms, capacity 1,508) and then four sections: leases, capital projects, maintenance, energy and costs. Those four come from the Java part.

A live dashboard on the map

This is the point of the whole exercise. The map is not a picture of the portfolio; it is a live dashboard built on top of a Class Loader. Everything in the right-hand panel is read from MREF at the moment you click the building, with your own session, and the last line of the panel says when.

The building panel with each section open in turn: leases, capital projects, maintenance, energy and costs. Every name is a link to the MREF record.
SectionWhat it tells youFor Charlotte Watson Center
Floors: rooms and capacityHow much space each floor holds. The blocks on the map are coloured by rooms per floor or by capacity (seats) per floor; click a floor to highlight it.6 floors, 894 rooms, 1,508 seats. The second floor is the densest: 383 rooms, 612 seats.
LeasesEvery lease on the building, its floors and its spaces: type, status and expiry date, soonest first.95 leases
Capital projectsProjects on the building with status, dates and budget.75 projects
MaintenanceWork tasks counted by status, the actual cost, and the open tasks with type and due date.1,003 open: 871 planned, 125 active; 391 completed
Energy & costsEnergy use and energy cost per year, then the latest cost period: operating, maintenance, utilities, energy, rent.Energy use down from 1.9M in 2012 to 1.1M in 2014; rent $340.8K and operating $271.4K in the latest period
Key idea · capacity is not occupancy

The floors show rooms and capacity: how many seats exist. They do not show how many people actually sit there. Occupancy needs the people-to-space allocations, which is the subject of the space planning post, and would be a natural next section for this dashboard.

In Maximo terms

Think of a Maximo Work Center or a start-centre with KPI portlets, but arranged on a map: one click on a location and you see its contracts, its projects, its work orders and its costs together. In Maximo you would assemble that from several applications; here one small Class Loader does it.

To put the page on a home page: Tools › Application Builder › Portal Builder, add a Portal Section of type External URL pointing to /html/en/default/rest/MREF3D/resource/index.html, then add that section to a portal. It is the same kind of section as the built-in GIS map sections.

Part 7The Java part: live data for one building

The page needs figures that no ready-made data source gives in one call: this building's leases, projects, work tasks, energy per year and latest costs. So the jar contains one class that reads them and returns JSON.

package com.tririga.custom;                 // required package

public class MREF3D implements IConnect {   // class name = Class Loader name

    public void execute(TririgaWS tws, HttpServletRequest req, HttpServletResponse res) {
        String b = req.getParameter("building");
        if (b == null || !b.matches("\\d{1,19}")) { res.setStatus(400); return; }   // validate input
        // read-only SELECTs on MREF's own data source, the id bound as a parameter
        // … write JSON to res
    }
}

Three rules make it work:

Called as /html/en/default/rest/MREF3D?building=10336477, it answers:

{ "building": 10336477,
  "leases":   [ 95 leases:  id, name, status, type, annual rent, expiry ],
  "projects": [ 75 capital projects: status, budget, committed, dates ],
  "energy":   [ {"year":2012,"use":1902824,"cost":86845},
                {"year":2013,"use":1333385,"cost":76302},
                {"year":2014,"use":1060894,"cost":57000} ],
  "costs":    { "period":"2014-10-01", "operating":271388, "maintenance":83956,
                "utilities":26929, "energy":12187, "rent":340819 },
  "maintenance": { "counts":[ Planned 871, Completed 391, Active 125, Closed 9 ], … },
  "asOf": "2026-10-03T04:44:46Z" }
Trap · this code runs inside the application server

A class in a Class Loader can reach the database and everything the server can reach. Treat an upload like a code deployment: review it, keep the source in version control, and keep it small. Ours only reads (SELECT), binds the building id as a parameter instead of pasting it into the SQL, caps every list, and rejects anything that is not a number.

In Maximo terms

If you have written an automation script behind a Maximo REST API endpoint, this is the same pattern: a small piece of server code that answers one question as JSON. The differences are that it is compiled Java, and that it queries the database directly, so you are responsible for not exposing more than the user should see.

Part 8Six traps

SymptomCauseWhat to do
HTTP 500 and AbstractMethodError on IConnect.executeThe jar was compiled against javax.servlet. MREF on MAS runs on Liberty with Jakarta EE, where the package is jakarta.servlet.Recompile against the server's Jakarta Servlet API. Old TRIRIGA extensions need this before they work on MREF.
/rest/<Name> returns an error instead of your answerPackage or class name does not match.Package com.tririga.custom, class name exactly the Class Loader name, same capitals.
A new zip is uploaded but the old page still showsThe browser cached the old files.Hard refresh. If you change the page often, add a version to the script URL.
A new jar is uploaded but the old code still answersThe old class is still loaded in memory.Save the record again so the Revision goes up. While you iterate, tick Development Mode. If the old code still answers, restart the application server at a quiet moment.
A manual fix on the server disappearsThe disk is a cache of the database copy.Change the resource file in the record.
A page loads but the map or script is blockedThe page loads something over http while MREF is on https.Use https everywhere. IBM's own EsriJS page had this problem on our system.
Try it in MREF Open Tools › System Setup › System › Class Loader and open EsriJS. Look at its resource files: you will find both Java and Web. Then open a building's GIS tab: that map is this Class Loader at work.

Part 9The built-in 3D: the BIM model viewer

MREF also has a 3D feature of its own, and it is a different thing. A building record has a 3D Model tab that shows the building's real geometry: the walls, rooms and equipment from the architect's BIM model (Building Information Model, usually made in Autodesk Revit).

Building › 3D Model tab: the Administration Building's Revit model in the Autodesk viewer, inside the building record.
Portfolio 3D (our Class Loader)3D Model tab (built in)
ShowsEvery building on a globe, as stacked floorsOne building's real model: rooms, walls, equipment
NeedsLatitude and longitude on the buildingA BIM model uploaded and linked to the building
Delivered asA Class Loader (Web zip + jar)A web application shipped with MREF
Outside serviceEsri mapsAutodesk Platform Services (formerly Forge)
Good forPortfolio overview, executivesFacility and space managers working inside one building

The BIM viewer needs three things, and a new admin usually misses the first:

  1. An Autodesk key. The viewer is Autodesk's, and the model is translated and stored in Autodesk's cloud. The key (a client ID and secret from an Autodesk Platform Services application) goes in Tools › System Setup › BIM Connector.
  2. A model linked to the building. In BIM Model Management you upload the Revit file and link it to the building record. The 3D Model tab simply lists the active model links of that building.
  3. Rooms that match. A room in the model is tied to an MREF space by the Revit unique ID stored on the space record. With that link, clicking a room in 3D opens its space record, and the reverse.
Tools › BIM Model Management › Model Files: our Autodesk bucket with seven Revit models, AdminBldg.rvt among them. The round button at the bottom right uploads a new one.

BIM Model Management has four tabs that follow the order of the work: Buckets (the storage folder in Autodesk's cloud, created once), Model Files (upload a Revit file; Autodesk translates it for the viewer), Buildings (link a model to an MREF building) and Viewer (check the result).

Trap · the key lives in two places

A key typed in BIM Model Management is kept only for your current session and is gone when you sign out. The one the 3D Model tab uses is the one saved in BIM Connector. If the tab opens but stays empty, and the browser console says "Auth request error", the saved key is missing or no longer accepted by Autodesk. Also, a model can only be read with the key of the Autodesk account that uploaded it: IBM's demo models cannot be opened with your key.

In Maximo terms

Maximo has the same idea as an add-on: the BIM viewer for Maximo, also built on Autodesk's viewer, linking model elements to assets and locations. In MREF it is part of the product, and the link is from model rooms to spaces.

Check yourself

1. You upload a new jar and restart nothing. The pod is replaced overnight. Is your extension still there in the morning?

Yes. The file is in the database; the new pod unpacks it again the first time it is used.

2. Your class is com.acme.Report in a Class Loader named Reports. Why does /rest/Reports fail?

For a web service, the class must be com.tririga.custom.Reports: fixed package, and the class named like the Class Loader.

3. An extension from an old TRIRIGA system returns HTTP 500 on MREF. What is the first thing to check?

Whether it was compiled against javax.servlet. MREF's server uses jakarta.servlet.

4. When would you choose Parent Last?

When your jar brings its own version of a library that MREF also contains, and your code needs your version.

5. The 3D Model tab is empty. Is that a Class Loader problem?

No. The BIM viewer is a built-in web application. Check the Autodesk key in BIM Connector and the model link on the building.

Glossary

Class Loader
An MREF record holding extra Java and Web files that the server loads while running.
Resource file
One uploaded file in a Class Loader: a jar (Java) or a zip (Web).
IConnect
The MREF interface a class implements to answer a web request at /rest/<Name>.
Parent First / Parent Last
Whether Java looks in MREF's libraries or in your jar first.
Development Mode
Reload the classes on every call; for development only.
Jakarta
The current name of Java's enterprise APIs; packages start with jakarta. instead of javax.
Portal section
A block on an MREF home page; one of type External URL can show a Class Loader page.
BIM
Building Information Model: the architect's 3D model with data on every room and element.
Autodesk Platform Services
Autodesk's cloud (formerly Forge) that stores and displays BIM models in the browser.
BIM Connector
The MREF setup record that holds the Autodesk key used by the 3D Model tab.

Want a custom page or a 3D view on your own MREF? Send me a message and I'll show you how we built this one.

Screens: IBM Maximo Real Estate and Facilities on IBM Maximo Application Suite, with IBM's GreenPoint demo data. MREF3D / Portfolio 3D is our own extension, not an IBM product. All names, amounts and dates are demo values.