May 28, 2012

Extending Maximo Business Objects

This entry is part of the Maximo Java Development series.

Sometimes it is necessary to override or extend the functionality in Maximo. This can be achieved by extending methods in the Maximo Business Objects.
This article outlines the process involved in extending the out-of-the-box psdi.app.item.Item class to initialize the description field to a specific value.

Create Java Classes
We will need to create two new files an Mbo and an MboSet. The cust.psdi.app.item.Item will extend the add() method in the psdi.app.item.Item class. It is a good common practice to use a well defined 1st level package name like 'cust' to group all the custom code.
Now open Eclipse and create a new Java class named cust.psdi.app.item.Item and paste the following code.
package cust.psdi.app.item;

import java.rmi.RemoteException;
import psdi.mbo.*;
import psdi.util.*;

public class Item extends psdi.app.item.Item implements psdi.app.item.ItemRemote
{
  public Item(MboSet ms) throws MXException, RemoteException
  {
    super(ms);
  }

  public void add() throws MXException, RemoteException
  {
    setValue("description", "TEST");
    super.add();
  }
}
Note how we have overridden the add() method of the psdi.app.item.Item class to insert the initialization of the description field.
Every time you override a Maximo method remember to call the super() method to preserve any preexisting behavior.

The ItemSet class does not contain any logic. It simply returns the reference of our new object.
package cust.psdi.app.item;

import java.rmi.RemoteException;
import psdi.mbo.*;
import psdi.util.*;

public class ItemSet extends psdi.app.item.ItemSet implements psdi.app.item.ItemSetRemote
{
  public ItemSet(MboServerInterface ms) throws MXException, RemoteException
  {
    super(ms);
  }

  protected Mbo getMboInstance(MboSet ms) throws MXException, RemoteException
  {
    return new Item(ms);
  }
}

Deploy Maximo EAR
After having compiled the two Java classes (should be done automatically by Eclipse), go in bin\cust\psdi\app\item folder and copy those two .class files into [SMPDIR]\maximo\applications\maximo\businessobjects\classes\cust\psdi\app\item.
Now rebuild the Maximo EAR file, redeploy it and restart your server (or use this fast method).

Update database
Now we have to tell Maximo to use the new classes. Open the Database Configuration application, select the ITEM object and put cust.psdi.app.item.ItemSet into the Class field.


Test
Launch Maximo and open the Item Master application. When the application launches, select insert from the toolbar. You will notice that the application will insert a new record with the description field defaulting to the value 'TEST'.

23 comments:

  1. What about stub classes? Do you only need to generate these if you are implementing a new method?

    ReplyDelete
    Replies
    1. Interesting question.
      I forgot to mention RMI stubs because I simply do not use them and I don't know why other Maximo developers give so much importance to this.
      You never need to generate stub classes unless you want to call an MBO method from a separate Java Virtual Machine. It may worth a separate article so I added this topic to the list.
      Thank you for your feedback.

      Delete
  2. I look forward to that article :). Its one area of Maximo that has always confused me especially once you start getting into systems with multiple JVMs set up for UI,CRON,REPORTS etc. Having a separate RMIRegistry JVM that holds the object references (?). And now the fact that with Maximo 7.5 (running against Java 1.5) stub files should be dynamically generated anyway(?) yet they still exist in the businessobject folder! *sigh*.

    ReplyDelete
  3. Hello Bruno,

    I have a problem with custom class. I did all the things you wrote. When I open Item Master application in Maximo 7.5 it gives a white webpage and some words. :S

    Something like "addLoadMethod("parent.setDisabled('mx513',false)"); addLoadMethod("parent.setDisabled('mx515',false)"); addLoadMethod("parent.setDisabled('mx517',false)"); addLoadMethod("parent.setDisabled('mx519',false)"); addLoadMethod("parent.setDisabled('mx521',false)"); addLoadMethod("parent.setDisabled('mx523',false)"); addLoadMethod("parent.setDisabled('mx525',false)"); addLoadMethod("parent.setDisabled('mx527',false)"); el = MAINDOC.getElement("mx172"); if(el) el.style.display="";
    Filter
    "

    Any help would be appreciated.. Thanks for advance.

    ReplyDelete
    Replies
    1. Please check in the Maximo logs.
      Do you see any Java exception?

      Delete
    2. Thank you for reply Bruno. But unfortunately there is no java exception in Maximo logs. Only I got such debug logs which I guess they are normal.

      "01 Aug 2012 11:25:42:169 [DEBUG] [MXServer] [CID-CRON-100] MAXPROP successfully fetched from maximo cache
      01 Aug 2012 11:25:42:169 [DEBUG] [MXServer] [CID-CRON-100] Getting MAXIMODD from maximo cache"

      I got stuck. :S..

      Delete
    3. I put new classes into this path.

      [SMPDIR]\maximo\applications\maximo\businessobjects\classes\cust\psdi\app\item.

      But I hadn't "cust\psdi\app\item" directory so I created it then put the classes into it.

      After rebuild maximo.ear

      Delete
  4. Hi Bruno, Thank you for tutorial and it worked. After I change ItemSet to ItemSet2, the relationship Item and Invertory broken. I mean when I open Invertory application fields which are related to Item gives invalid binding. Do we need to do some works to do for binding issue?

    Thank you very much.

    ReplyDelete
    Replies
    1. Ensure that you have specified the right class in the ITEM object in Database Configuration.
      Is the ItemSet2.class file deployed?
      I think you have also renamed Item class to Item2. Have you deployed Item2.class file?
      Have you changed the following line into ItemSet2 class?
      return new Item(ms); >> return new Item2(ms);

      Delete
    2. Hi Bruno,

      I need to call Mbo duplicate action via automation script and override it.
      Can you help

      Delete
  5. Can you please help me to write My first MBO.From the first step.
    I would like to Copy SR custom fields values to Workorder whenever user make changes to Internalpriority.

    ReplyDelete
  6. Hi Bruno I am new to this java customization. I have seen many examples you explained in easy way this is very helpful to me. Can you please explain some simple coding examples in create,update and delete operations (for asset, WO etc...).

    ReplyDelete
  7. Hi Bruno, can you tel me how to calculate the total of line prices displayed on the tab POLINE (i.e I wante to calculate the SUM OF POLINE.LINECOST).

    Thank you.

    ReplyDelete
    Replies
    1. try this action class, you can use it in workflow:

      package custom.action.pr;

      import java.rmi.RemoteException;

      import psdi.common.action.ActionCustomClass;
      import psdi.mbo.MboRemote;
      import psdi.mbo.MboSetRemote;
      import psdi.util.MXException;

      public class test implements ActionCustomClass{

      @Override
      public void applyCustomAction(MboRemote arg0, Object[] arg1)
      throws MXException, RemoteException {

      MboSetRemote prLines = arg0.getMboSet("PRLINE");
      if (prLines.count() != 0) {
      MboRemote prLine;
      float summ = 0;
      for (int j = 0; (prLine = prLines.getMbo(j)) != null; j++) {
      summ = summ + prLine.getFloat("LINECOST");
      }
      }
      }
      }

      Delete
  8. Hi Bruno,

    How to skip a parent class method when you extend parent class. I am adding a new mbo to an mboset like mboset.add() due some code in add method am facing an concurrentmodification exception. so i want to skip the functionality in add method and add a new record. can you please help me out.

    Thanks,
    Ganesh.

    ReplyDelete
  9. Hello Bruno,
    I am new to mbo customization and i tried extending the Item class the way you have mentioned and also tried the fast approach(5 minute step 4 approach) mentioned by you to deploy the ear file.
    However when i opened the Item Application It showed Gabare characters like "INSERT" etc...
    Any pointers where things went wrong?

    ReplyDelete
    Replies
    1. When the application fails to load correctly you should see some exceptions in the SystemOut.log file.

      Delete
  10. Hi Bruno,

    kindly I tried to implement the above example and got the below error in the log file

    BMXAA4160E - A major exception has occurred. Check the system log to see if there are any companion errors logged. Report this error to your system administrator. cust.psdi.app.item.ItemSet.(psdi.mbo.MboServerInterface)

    [5/8/14 20:47:19:283 GMT+02:00] 00000046 SystemErr R Caused by: java.lang.NoSuchMethodException: cust.psdi.app.item.ItemSet.(psdi.mbo.MboServerInterface)
    [5/8/14 20:47:19:283 GMT+02:00] 00000046 SystemErr R at java.lang.Throwable.(Throwable.java:67)
    [5/8/14 20:47:19:283 GMT+02:00] 00000046 SystemErr R at java.lang.Class.throwNoSuchMethodException(Class.java:277)
    [5/8/14 20:47:19:283 GMT+02:00] 00000046 SystemErr R at java.lang.Class.getConstructor(Class.java:333)
    [5/8/14 20:47:19:283 GMT+02:00] 00000046 SystemErr R at psdi.server.AppService.getMboSet(AppService.java:481)
    [5/8/14 20:47:19:283 GMT+02:00] 00000046 SystemErr R ... 60 more

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. i am beginner in maximo , how can i extend class ?? anyone help ?

    ReplyDelete
  13. it show "invalid binding" when i apply that class in my object.

    ReplyDelete