How to run BIRT report from Java class

I have seen many people on different Maximo forums/blogs have requirement to implement functionality as a cron task or custom class action that will generate report in Maximo, export it as pdf and send it as attachment in an email. So I decided to check how this can be implemented and I have found out a solution for Maximo V7.1, but I believe that same solution is applicable for any later version of Maximo.

First thing that I looked for  in order to find solution for this was to check Maximo services in Application Designer. I have found out for reporting there are several services, but the one that is providing functionality to generate and export reports is registered in Maximo as a BIRTREPORT. Its name tells us that service is used for BIRT reports and solution that I am about to describe I have tested only for BIRT reports, so in case your Maximo installation is configured to use some other reporting framework like Actuate or Cognos, you will have to test it yourself.

From definition of the service, you can see that service is using class: com.ibm.tivoli.maximo.report.birt.admin.ReportAdminService. Looking at class methods from Maximo JavaDocs I have found two that are doing exactly what is needed for our case:

public byte[] runReport(UserInfo userInfo, String reportName, String appName, ReportParameterData parameterData, String outputFileName, String outputFormat)

public byte[] runReport(UserInfo userInfo, String reportName, String appName, ReportParameterData parameterData, String outputFileName, String outputFormat, Map<String, Object> additionalInfoMap)

Actually first method is calling second method providing null as a additionalInfoMap parameter. Having this in mind I have developed small custom batch class:

package com.anjadev.app.testcron;

import com.ibm.tivoli.maximo.report.birt.admin.ReportAdminServiceRemote;
import com.ibm.tivoli.maximo.report.birt.runtime.ReportParameterData;
import psdi.mbo.MboRemote;
import psdi.mbo.MboSetEnumeration;
import psdi.mbo.MboSetRemote;
import psdi.mbo.SqlFormat;
import psdi.server.MXServer;
import psdi.server.SimpleCronTask;
import psdi.util.logging.MXLogger;
import psdi.util.logging.MXLoggerFactory;

public class TestReportCron extends SimpleCronTask{
   MXLogger logger = MXLoggerFactory.getLogger("com.test.TestReportCron");

   @Override
   public void cronAction() {
      try{
         ReportAdminServiceRemote reportAdminService =
            (ReportAdminServiceRemote) MXServer.getMXServer().lookup("BIRTREPORT");
	 String emailSendTo = getParamAsString("emailsendto");
	 String emailSendFrom = getParamAsString("emailsendfrom");
	 String reportName = getParamAsString("reportname");
	 String whereClause = getParamAsString("whereclause");
	 String objectName = getParamAsString("objectname");
	 String appName = getParamAsString("appname");
	 ReportParameterData parameterData = new ReportParameterData();
         MboSetRemote mboSetRemote = MXServer.getMXServer().getMboSet(objectName, getRunasUserInfo());
	 mboSetRemote.setWhere(whereClause);
	 mboSetRemote.reset();
	 MboSetEnumeration mse = new MboSetEnumeration(mboSetRemote);

         //send email with report attached for each mbo
	 while (mse.hasMoreElements()) {
	   MboRemote mbo = mse.nextMbo();
	   parameterData.addParameter("where_param", mbo.getUniqueIDName()+"="+mbo.getUniqueIDValue());
		MboSetEnumeration mse = new MboSetEnumeration(mboSetRemote);
		//send email with report attached for each mbo
		while (mse.hasMoreElements()) {
		   MboRemote mbo = mse.nextMbo();
                   parameterData.addParameter("where", mbo.getUniqueIDName()+"="+mbo.getUniqueIDValue());
                   byte[] report = reportAdminService.runReport(getRunasUserInfo(), reportName, appName,
                      parameterData, "report.pdf", ReportAdminServiceRemote.OUTPUT_FORMAT_PDF);
                   parameterData.clearAllParameters();
                   //send email with attachment
         }
      }catch (Exception e) {
         logger.error(e.getStackTrace());
         //handle exception
      }
   }
}

I shall quickly go trough the code of the cronAction method, first line of this method is to get instance of BIRTREPORT service and next lines of code below and up to the while loop represent reading of cron task parameters from setup of cron task  in Maximo (I shall not describe here how to setup cron task since it will be described in details as a part of Boot Camp article series for Maximo), based on those parameters system fetches the set of records. In this case I assume that for each mbo record system should generate  report and and send it to certain emails set as parameters of cron task.

Looking at the while loop, you can see that first we set a parameter of the report named where_param, in my case I have created a report that requires this where clause in order to fetch the record and populate the report with it, for sure you can think of another way how to populate the report. After that comes call to method in order to generate a report itself. It is important to mention one should need to grant privilege to user, that cron task is running under, to be able to run reports for specified application (second and third parameter). Also in case you would like to generate report in HTML format you can specify last parameter of runReport method as ReportAdminServiceRemote.OUTPUT_FORMAT_HTML, but have in mind that byte array that is returned by this method will represent zip file, this file will contain html report and additional files (images, css, etc) required in html report itself. Finally after report is generated, method returns an array of bytes that should be sent as an attachment to email. Now sending an email with attachment is not topic of this article but just for your reference this can be done in two ways:

1. Using MXServer.sendEmail method, in this case you shall need to write byte array into some temp file on the disk, since sendEmail method is accepting path to the file as string type. Also in this case take care that after email is send you need to clean up things behind you by deleting this temp file.
2. Using standard Java mail library, in this case you can avoid creating temp file.

I believe that this article will be useful in some of your projects, in case you have additional questions please submit it through below form and I shall be glad to answer it. Have a nice day …

Posted in IBM Maximo Tagged with: , , ,
5 comments on “How to run BIRT report from Java class
  1. peter says:

    Yes very informative, but I was thinking if this code can accomplish in Maximo Automation Script..? if so how can we convert this code in Jython script.

    • Dorde Popovic says:

      Yes, this can be used in automation script, conversion is simple: copy paste code in method and import all java classes into script. Now next step is to create action that will call script. This action cab be called from escalation, workflow you can associate it with sigoption of an application and execute it on click of a button. But you cannot use it for cron.

      • peter says:

        Thanks Dorde, but I tried this already in Automation script it works, the only problem was the PDF attachment was empty no data row was fetched, the header and the footer of the reports was there, if you have any idea what went wrong on this.

        Thanks.

        • Dorde Popovic says:

          This sounds more like an issue with report, please check if you have some parameters to be sent to report. I do not think problem is with the script to execute it since you are getting pdf.

        • Monem says:

          Hello Peter
          could you please give me the script that you used

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe for Newsletter

Categories