Category: Order

Manipulating Chain of Java Extensions for the upgrade/installation process

 

I recently had to upgrade a pretty complex system. The original environment includes Maximo and ICD, and two large customization packages, one extended by the other (let’s call them package XXX extended by package YYY). The target system is the latest Maximo + ICD 7.6.1, plus 4 add-ons which include Oil & Gas and Utilities.

Customization was written by 3 different third parties over a long period of time and the source code was lost. This posed some challenges related to preserving customization and I had to spend a bit of time to figure it out. Below are some of the gotchas I learnt after the project:
 
Problem 1: Ensure customization is preserved after the upgrade

After reviewing the SMP folder, I found about 300 extended Java class files, but the product.xml files only cover about 20-30% of them; worse, some data are not even up-to-date. After the initial attempt to correct these files, I decided to simply ignore them, and build new product.xml files from scratch. Below are some of the key steps I had to do:
 
  • List out all extended java class files found in the SMP folder (using the command: dir /s /b  >list.txt) and put them in an Excel sheet
  • Use SQL to search from the DB any usage of custom Java code, put this list into another Excel sheet
  • Match the two sheets above to identify any missing files
  • Use a decompiler to view the code of each file to determine what is the original class it extends, and the type of the class (which I put into: Action, Bean, Cron, Event, Field, Object, Util)
  • For each of the class types, use Excel to generate an XML element as the follow examples:
  • After generating those elements, I put them together into newly created XML files.

Problem 2: Manipulating chain of extension without having Java source code:

The updated process took 6 hours, and after it finished and I can start Maximo. However, I freaked out when I looked into the MboSet class used by various objects. For example, in the WorkOrder object, the class used is psdi.pluss.app.workorder.PlusSWOSet. Initially, I thought the custom classes were wiped out after the upgrade. But after some investigation, I realized that due
to the upgrade and installation of new add-ons, Maximo has updated the classes (through the mean of binary code injection) to modify the chain of extension like this:

Before:  YYYWOSet XXXWOSet TloamWOSet PlusPWOSet WOSet


After:  PlusSWOSet > PlusGWOSet > YYYWOSet > XXXWOSet > TloamWOSet > PlusPWOSet > WOSet


After spending some time reading various IBM tech notes, I learnt that, in the past, we need to create a file with the exact name as: “a_customer.xml” to maintain metadata about customization. In the newer version (not exactly sure from what version, probably 7.5), we actually SHOULDN’T name it “a_customer.xml”. Because the file name makes it top of the list (in alphabetical order), and thus, becomes the first product to extend the core Maximo classes. For example, if you only have Core Maximo, Oil & Gas Add-on, and your custom package, if you name it a_customer.xml, the O&G package name is plusg, thus the extension chain would become: PlusGWOSet > CUSTOMWOSet > WOSet


If I like my custom class to be the last one that extends everything else, I actually should name it z_customer.xml, or anything that comes last in term of alphabetical
order. So I named the product XML files for the two custom packages z1_XXX
and z2_YYY.

For some unknown reasons, using just file name doesn’t give me the desirable outcome (probably due to  some undocumented logic), I had to use the <depends>
tag inside the two product XML files. From my experiment, by having the <depends> tag, the updatedb process will now ignore the file name rule, which means it doesn’t matter if you name it a_customer or z_customer anymore. The classes in your package will be extended after all packages listed in the <depends>
tag

To illustrate this point, below is the <depends> tag of my original z2_YYY.xml file:

It means the YYY package will extend the XXX package, then extend a bunch of packages (which included in the ICD product).

I updated the <depends> tag of the z2_YYY.xml file as follows:

Notice now I inserted three other packages before z1_XXX. After I updated the files, I ran updatedb process again (Even if there’s no update, updatedb will still update the java class files. With newer Maximo versions, you can run updatedblitepreprocessor.bat to do the same). With this, the updated process displays the product installation order as below:

Checking the class files, I got the extension in the desired order:

YYYWOSet > XXXWOSet > TloamWOSet > PlusSWOSet > PlusGWOSet > PlusPWOSet > WOSet

One more note, during the process, I found some of the files that get extended in an endless loop, for example:


YYYWOSet > PlusSWOSet > PlusGWOSet > TloamWOSet
> PlusPWOSet > XXX > TloamWOSet

This caused Maximo to fail when opening the app and crashed Eclipse when I tried to decompile the file. It turned out the reason is I used the wrong XML tag for the class type i.e. I should have used <Mbo….>  and <MboSet…> for object class rather
than <Class…> tag.

Another note is, due to some bugs or unknown logic, I had to play around a little with the product listed in the <depends> tag to get to the desired order as it doesn’t seem to work exactly as documented.

Hope this helps.

Blanket Contract and Procurement in Maximo

A friend of mine who has experience with SAP asked whether Maximo can handle a “Blanket PO” process similar to SAP. I sent him my answer based on the scenario and requirement he provided and think it is probably worth posting here as some other people may find it interesting:

In the Purchase Contracts application, we can create a new Purchase Contract of type “Blanket”  and give it a Maximum Amount say $1.5M. Some companies call it “Budget” because this is the limit a user can use to release Purchase Orders (PO). This is called “Release PO” in Maximo, but I saw many of my clients in the energy sector refer to it as “Call-Out” or “Work order”. Blanket Contract is also sometimes referred to using different terms such as Frame Contract, Framework Contract, or Price Contract. I mention this because the “Work Order” PO can easily be confused with normal maintenance Work Order, and “Price contract” in this case can easily be confused with the “Price Contract” type in Maximo which works a bit differently.

To create a Release PO, on the Contract app, we use the “Select Action >> Create Release PO”, and then select the contract items we want to procure. We can choose not to select any existing contract item, generate an empty PO, and add service/material items to the PO lines later. The total amount of the PO will still be counted against this Contract.

GL Account is specified in PO, not in Contract because the contract is an agreement between the operating company and a 3rd party vendor; it is generally to define terms and conditions and set a fixed price for certain goods or services. When the good or service is actually ordered (by issuing a Release PO), we will have a better idea of where and how it is used (on what project/work order or on what location/asset/cost centre?).

In the Purchase Order application, we can distribute the cost of each line item to charge against different cost centres or GL accounts for more detailed financial reporting. To do this, we can select a line and click on the “Distribute Cost” button and specify the cost and GL account that we want to charge against. This information will also be copied to the Invoice when creating an Invoice record so that accountants can determine what expenses will be recorded against what accounts.

The rest of the steps are similar to the standard procurement process: we can receive material/service using the Receiving application, and we can create an Invoice against the receipts. (In the Receiving application, even with the latest version, Maximo still treats each line item received as a separate transaction, I prefer IBM to introduce an app that groups all items received each time into one Receipt header record which can be used to enter details like the receiver, inspector, and actual receipt date).

If Maximo is integrated with the Finance system, generally, items in an approved PO are posted as a “commitment” transaction, items received into inventory are posted as “accrual”, and items/services purchased against an Asset/Location, Work order, or simply a GL, which are referred to as “Direct Issue” item in Maximo, are posted as “expense”, and Invoice is posted as “payable”, “tax”, and “expense” transactions.

In the Contract application, we can open a Blanket Contract, and click on “Select Action >> View Release Cost” to see with the original “budget”, how many Release POs have been issued, the total committed amount, the total received, and the remaining of the “budgeted” amount we have left to spend on future release.