Tag Archives: Oracle BI Suite EE

The Secret Life of Conditional Formatting in OBIEE

When dealing with conditional formatting the GUI allow us to add as many formats as we want, but every single format has a unique and single condition, not more, not less. In this post I am going to show how it is possible in OBIEE to use multiple conditions to define a special formatting on an analysis column. Sometimes the requirement for conditional formatting is a little more complex, mainly when using pivots, requiring 2 conditions like for example “year = current-year AND country = UK”. In general we try to manage this requirement by a set of conditional formats sorted in a specific order trying to achieve something as close as possible to this, sometimes also setting one format first and then overriding it back in some cells of a pivot to make them looks like the cells without special format. It would be a lot easier to be able to just define a more complex rule for the special format but the GUI doesn’t allow it.

Does it means OBIEE can’t manage complex conditions formatting? No, not at all! Let me introduce you the secret life of conditional formatting…

Before we look at the practical implementation, first let us consider the “history” of conditional formatting, and why we can be optimistic that the method I describe will work.

It must be noted that because it’s not a functionality available through the GUI there is no guarantee it will work correctly or OBIEE will support it in futures releases, but for me it works fine in OBIEE 11.1.1.7 and related patched versions.

Some theory

OBIEE Analyses are stored in an XML format that OBIEE interprets when building and running the report. Using the Advanced tab of an analysis we can examine this XML. The XML can tell you a lot of information and give some hints about functionality the GUI doesn’t allow to perform but based on the XML you can easily guess it will work if coded by hand. Let’s focus on the XML related to conditional formatting as it’s the topic of this post.

Part of the XML standard is an associated XSD file, the XML Schema definition. OBIEE’s XML honours this and we can use this to examine the XML that OBIEE will accept and expect for an analysis. jDeveloper is a good tool to analyze XSD thanks to its built-in “design/source” viewer.
This is the graphical representation of the XSD describing the code behind conditional formatting (click to zoom). If you compare it with the XML you will recognize most of the elements. The important element is into the formatRule block, inside condition: the XSD expect a sawx:expr element there.

cond-format_displayFormat_XSD

Why is it important? Well if you look at a separate part of the XSD, which deals with the filters in an analysis.

cond-format_filter_XSD

Surprise: it’s the same sawx:expr. What does it mean for us? Because the filters accept AND and OR logical operator to join filters together, the XML of the analysis will accept the same syntax in the conditional formatting condition block. There is no guarantee at this point it will work, the XML will be valid but if the code parsing and interpreting the XML doesn’t implement this functionality it will not produce anything (or an error in the worst case). Time to move to the practical part and try it.

Step by step example

I start by creating my pivot where I display Revenues by Country (filtered list to some elements) and Line of Business (LOB).

cond-format_simple_pivot

Now my target is to highlight figures for “Switzerland” in the countries and “Games” in the LOB, so I add a conditional format on the Revenue column and set a red background for Switzerland and yellow background for Games.

cond-format_normal_condition

As expected the result is my pivot with a red row (for Switzerland) and a yellow column (for Games).

cond-format_normal_condition_result

It doesn’t really looks good because the intersection of Switzerland and Games will use the format of the last matched condition, in my case the yellow of Games because it’s the second conditional formatting defined. I would prefer to have this intersection in a nice orange background, but the GUI doesn’t have an option to combine conditions.

The GUI doesn’t do it but it doesn’t mean it’s not possible! Let’s have a look at the XML managing the conditional formatting. First we look an example of the code producing the red background based on the country.

<saw:conditionalDisplayFormat>
  <saw:formatRule>
    <saw:condition>
      <sawx:expr xsi:type="sawx:comparison" op="equal">
        <sawx:expr xsi:type="sawx:columnRefExpr" columnID="c632a4f0428ecfa91"/>
        <sawx:expr xsi:type="xsd:string">Switzerland</sawx:expr>
      </sawx:expr>
    </saw:condition>
    <saw:formatSpec backgroundColor="#FF0000" wrapText="true"/>
  </saw:formatRule>
</saw:conditionalDisplayFormat>

Now, as we saw before, the XSD allow me to use the syntax of filters, including filters containing logical operators (AND, OR) to join conditions together. So if I add the XML with the AND operator I will be able to use the condition country=Switzerland AND LOB=Games to apply a different format.

In a text editor I prepare the new XML for the analysis with an additional <saw:conditionalDisplayFormat> element with my new hand-made condition.

It looks good and I can now try to paste it back in OBIEE and see if the syntax is correct and my XML will be accepted: in the Advanced tab of the analysis I replace the existing XML with my own version of the code.

<saw:conditionalDisplayFormat>
  <saw:formatRule>
    <saw:condition>
      <sawx:expr xsi:type="sawx:logical" op="and">
        <sawx:expr xsi:type="sawx:comparison" op="equal">
          <sawx:expr xsi:type="sawx:columnRefExpr" columnID="c3d00191589cdd4e2"/>
          <sawx:expr xsi:type="xsd:string">Games</sawx:expr>
        </sawx:expr>
        <sawx:expr xsi:type="sawx:comparison" op="equal">
          <sawx:expr xsi:type="sawx:columnRefExpr" columnID="c632a4f0428ecfa91"/>
          <sawx:expr xsi:type="xsd:string">Switzerland</sawx:expr>
        </sawx:expr>
      </sawx:expr>
    </saw:condition>
    <saw:formatSpec backgroundColor="#FF9900" wrapText="true"/>
  </saw:formatRule>
</saw:conditionalDisplayFormat>

When clicking “Apply XML” OBIEE will parse and evaluate the XML. If there is an error a message is displayed and the code is not applied (so as to not break the analysis). If you get an error, double check your XML, make sure every tag you open is closed and read the error message as it says what is the problem.

cond-format_edit_xml

Time to click the Results tab and check the new result of my analysis. YES! There is a nice orange background in the intersection now, proving that even if the GUI can’t do it OBIEE is able to accept complex conditions to define conditional formatting.

cond-format_normal_condition_final_result

What do we see if we check the properties of the column in the GUI? As you can see in the next screenshot we see there is a condition setting an orange background, but the condition itself is just shown as sawx:expr:sawx:logicaland. Where does this text come from? It’s a concatenation of the name of the first XML tag containing the logical operator and the values of the attributes of the tag itself. So if you use a OR instead of AND you will see a condition named sawx:expr:sawx:logicalor.

cond-format_final_condition

Can we edit the condition in the GUI? Not really, the edit window is opened, but the formula will not be recognized and if you set an operator and a value you will lose your hand-made conditional formatting and generate a meaningless piece of XML, so don’t do it for any reason. On the other hand the format can be edited using the GUI with no impact on the rule, so feel free to do it and correct the format if you don’t feel comfortable coding a format by hand in the XML.

cond-format_final_condition_edit

To resume, and some advice

  • It’s possible to have a complex formula as condition in a conditional formatting rule.
  • It’s not supported by the GUI, needs to be done by hand in XML.
  • Do it as one of the last steps when building an analysis because you can’t edit it via the GUI.
  • Be familiar with the produced XML before you play with it.
  • Use the Filters section to create the condition and avoid mistakes, so a copy/paste of the generated rule will help in creating the condition.
  • Document, document, document! As the condition is visible only in the XML document it somewhere, even just in a Static Text view you add to the analysis itself (and don’t display on the screen).
  • Be aware of the maintenance overhead that direct XML manipulation will have – don’t abuse the “cheating”.
  • If you don’t want to hack the XML, an alternative solution can be to use a extra column added to the analysis to evaluate the complex condition and produce a flag used for the conditional formatting. The downside of this is that the condition will be sent to the database as part of the query for evaluation.

Rittman Mead BI Forum 2014 Registration Now Open – Don’t Miss Out!

Just a quick reminder to say that registration for the Rittman Mead BI Forum 2014 is now open, with the speaker and presentation list now up on the event website. As with previous years, the BI Forum runs in Brighton on the first week, and then moves over to Atlanta on the second, with the dates and venues as follows:

We’ve got a fantastic line-up of sessions and speakers, including:

  • Oracle ACE and past BI Forum best speaker winner Kevin McGinley, on adding third-party visualisations to OBIEE
  • Sessions from TimesTen PMs Chris Jenkins and Susan Cheung on what’s coming with TimesTen
  • Wayne Van Sluys from InterRel, on Essbase optimisation
  • Oracle’s Andrew Bond, and our own Stewart Bryson (Oracle ACE) with an update to Oracle’s reference BI, DW and Big Data Architecture
  • Dan Vlamis on using Oracle Database analytics with the Oracle BI Applications
  • Sessions from Oracle’s Jack Berkowitz, Adam Bloom and Matt Bedin on what’s coming with OBIEE and Oracle BI Applications
  • Peak Indicators’ Alastair Burgess on tuning TimesTen with Aggregate Persistence
  • Endeca sessions from Chris Lynskey (PM), Omri Traub (Development Manager) on Endeca, along with ones from Branchbird’s Patrick Rafferty and Truls Bergersen
  • And sessions from Rittman Mead’s Robin Moffatt (OBIEE performance), Gianni Ceresa (Essbase) and Michael Rainey (ODI, with Nick Hurt from IFPI)

NewImage

We’ve also got some excellent keynote sessions including one in the US from Maria Colgan on the new in-memory database option, and another in Brighton from Matt Bedin and Adam Bloom on BI in the Cloud – along with the opening-night Oracle product development keynote in both Brighton and Atlanta.

We’re also very exited to welcome Lars George from Cloudera to deliver this year’s optional one-day masterclass, this year on Hadoop, big data, and how Oracle BI&DW developers can get started with this technology. Lars is Cloudera’s Chief Architect in EMEA and an HBase committer, and he’ll be covering topics such as:

  • What is Hadoop, what’s in the Hadoop ecosystem and how do you design a Hadoop cluster
  • Using tools such as Flume and Sqoop to import data into Hadoop, and then analyse it using Hive, Pig, Impala and Cloudera Search
  • Introduction to NoSQL and HBase
  • Connecting Hadoop to tools such as OBIEE and ODI using JDBC, ODBC, Impala and Hive

If you’ve been meaning to take a look at Hadoop, or if you’ve made a start but would like a chance to discuss techniques with someone who’s out in the field every week designing and building Hadoop systems, this session is aimed at you – it’s on the Wednesday before each event and you can book at the same time as registering for the main BI Forum days.

NewImage

Attendance is limited to around seventy at each event, and we’re running the Brighton BI Forum back at the Hotel Seattle, whilst the US one is running at the Renaissance Midtown Hotel, Atlanta. We encourage attendees to stay at the hotel as well so as to maximise networking opportunities, and this year you can book US accommodation directly with the hotel so you can collect any Marriott points, corporate discounts etc. As usual, we’ll take good care of you over the two or three days, with meals each night, drinks receptions and lots of opportunities to meet colleagues and friends in the industry.

Full details are on the BI Forum 2014 web page including links to the registration sites. Book now so you don’t miss-out – each year we sell-out in advance, so don’t leave it to the last minute if you’re thinking of coming. Hopefully see you all in Brighton and Atlanta in May 2014!

OBIEE Dashboard prompt: at least one mandatory

It’s almost two years now I joined the Rittman Mead team and never wrote on this blog before, time to start. For this first post nothing long, I wanted to share something I had to setup few weeks ago on a project and it can be interesting for others as well.

My need was related to dashboard prompts: it’s easy to have all of them optional (the default behavior) or the make a prompt (or many of them) mandatory. But if you need to have at least one mandatory field between many in a dashboard prompt? For example if you have a prompt to select a customer and it contains 2 fields: “customer name” and “customer number”. A user can select a customer based on its name or number and I want the user to always select a customer, so at least one of these 2 fields needs to be mandatory.

There is not a magic checkbox in OBIEE to achieve this behavior, setting both fields as mandatory means the user need to enter the customer details twice all the time, not acceptable from a usability point of view.

There is a way to simulate this behavior and will not impact (or in a negligible way) performances without generating unneeded queries on the database.

First I create my dashboard prompt and for my 2 fields I set a presentation variable: pv_CustomerName and pv_CustomerNumber in my example.

dbprompt_prompt_customer_name

Then I create an analysis where I will perform the check to detect if at least one of my prompt fields is set. Add a single column, not important which one of your subject area because I will edit the formula to set a fixed value, a value I’m absolutely sure doesn’t exist in my prompted fields, so for example something like ‘x0xx_I_can_not_exist_xx0x’. Thanks to this unique column with a fixed value this analysis will never send a query to the database, the BI server will manage it.

dbprompt_condition_analysis_column_formula

Time to add some filter to this analysis, my filters will be set on this single column and will use the presentation variables I defined in the dashboard prompt.  I set the condition to be ‘is equal to / is in’ and as value I choose “Presentation variable” and enter the name of the first of my variables and, really important, I set a default value: x0xx_I_can_not_exist_xx0x. Does it remind you something? Yes, it’s the same strange value I manually set as being the value of the my unique column (really important, it must be exactly the same value).

dbprompt_condition_analysis_add_filter

What will this filter do? If there is no variable set the filter is like a “1=1″, if there is a variable set from the prompt it will behave like a “1=2″. Now add all the other presentation variables in the same way using a “AND” condition.

dbprompt_condition_analysis_filters

This analysis will return exactly a unique row with the value of “x0xx_I_can_not_exist_xx0x” or no rows at all, I will use it as a condition to know if at least one dashboard prompt is set or not.

dbprompt_condition_analysis_result

Save this analysis ideally with the word “condition” in the name as we will use it as condition to know if the prompt is filled or not (mine is called “condition_no_prompt_set”).

Time now to finish the work as we have all the elements. Edit the dashboard where you want to add the “at least one mandatory” field functionality, add the dashboard prompt and 2 additional sections: in one of these sections add the analysis you want to run when at least one field is set, in the other one add a text object with a polite message asking the user to use at least one of the dashboard prompt fields.

dbprompt_dashboard_2_sections

Last step is to add conditions to decide when to display the first or the second section.

dbprompt_dashboard_add_condition

For the one with the message set a condition when the “condition_no_prompt_set” analysis return 1 row, in the other section (the one with the analysis to be executed if the prompt is correctly set) set a condition on the same “condition_no_prompt” analysis when it return 0 rows.

dbprompt_dashboard_condition_no_prompt

dbprompt_dashboard_condition_prompt_ok

Done! I have my “at least one mandatory dashboard prompt” as you can see in the next screenshots:

dbprompt_final_output_no_prompt

dbprompt_final_output_customer_name

dbprompt_final_output_customer_number

And the nice thing is that the condition managing the display doesn’t generate any query on the database (as you can see in the logs below), only the BI server will get the query and it’s a really simple one, similar to a “SELECT ‘xxxx’ FROM dual WHERE 1=1″.

dbprompt_condition_query_log1
dbprompt_condition_query_log2

Rittman Mead BI Forum 2014 Now Open for Registration!

I’m very pleased to announce that the Rittman Mead BI Forum 2014 running in Brighton and Atlanta, May 2014, is now open for registration. Keeping the format as before – a single stream at each event, world-class speakers and expert-level presentations, and a strictly-limited number of attendees – this is the premier Oracle BI tech conference for developers looking for something beyond marketing and beginner-level content.

This year we have a fantastic line-up of speakers and sessions, including:

  • Oracle ACE and past BI Forum best speaker winner Kevin McGinley, on adding third-party visualisations to OBIEE
  • Tony Heljula, winner of multiple best speaker awards and this year presenting on Exalytics and TimesTen Columnar Storage
  • Sessions from TimesTen PMs Chris Jenkins and Susan Cheung on what’s coming with TimesTen
  • Edward Roske, author of multiple books on Essbase, on Essbase optimisation
  • Oracle’s Andrew Bond, and our own Stewart Bryson (Oracle ACE) with an update to Oracle’s reference BI, DW and Big Data Architecture
  • Sessions from Oracle’s Jack Berkowitz, Adam Bloom and Matt Bedin on what’s coming with OBIEE and Oracle BI Applications
  • Endeca sessions from Chris Lynskey (PM), Omri Traub (Development Manager) on Endeca, along with ones from Branchbird’s Patrick Rafferty and Truls Bergersen
  • And sessions from Rittman Mead’s Robin Moffatt (OBIEE performance), Gianni Ceresa (Essbase) and Michael Rainey (ODI, with Nick Hurt from IFPI)
NewImage

We’ve also got some excellent keynote sessions including one in the US from Maria Colgan on the new in-memory database option, and another in Brighton from Matt Bedin and Adam Bloom on BI in the Cloud – along with the opening-night Oracle product development keynote in both Brighton and Atlanta.

We’re also very exited to welcome Lars George from Cloudera to deliver this year’s optional one-day masterclass, this year on Hadoop, big data, and how Oracle BI&DW developers can get started with this technology. Lars is Cloudera’s Chief Architect in EMEA and an HBase committer, and he’ll be covering topics such as:

  • What is Hadoop, what’s in the Hadoop ecosystem and how do you design a Hadoop cluster
  • Using tools such as Flume and Sqoop to import data into Hadoop, and then analyse it using Hive, Pig, Impala and Cloudera Search
  • Introduction to NoSQL and HBase
  • Connecting Hadoop to tools such as OBIEE and ODI using JDBC, ODBC, Impala and Hive

If you’ve been meaning to take a look at Hadoop, or if you’ve made a start but would like a chance to discuss techniques with someone who’s out in the field every week designing and building Hadoop systems, this session is aimed at you – it’s on the Wednesday before each event and you can book at the same time as registering for the main BI Forum days.

NewImage

Attendance is limited to around seventy at each event, and we’re running the Brighton BI Forum back at the Hotel Seattle, whilst the US one is running at the Renaissance Midtown Hotel, Atlanta. We encourage attendees to stay at the hotel as well so as to maximise networking opportunities, and this year you can book US accommodation directly with the hotel so you can collect any Marriott points, corporate discounts etc. As usual, we’ll take good care of you over the two or three days, with meals each night, drinks receptions and lots of opportunities to meet colleagues and friends in the industry.

Full details are on the BI Forum 2014 web page including links to the registration sites. Book now so you don’t miss-out – each year we sell-out in advance, so don’t leave it to the last minute if you’re thinking of coming. Hopefully see you all in Brighton and Atlanta in May 2014!

Using Groovy instead of WLST for OBIEE Systems Management

I remember some years back when Rittman Mead first received the OBIEE 11g beta and I tried installing it for the first time. It was a nightmare. If you think the 11.1.1.3 release was challenging, you should have tried working with any one of the betas. It was with these first few releases that Weblogic was injected into my world. Some time around the first month of starting the beta, I recall Mark Rittman saying something along the lines of: “all the Fusion Middleware stuff looks interesting, but I’m glad we won’t have to know anything about that.” You see… I just wanted a nice career in BI, but here I am writing a blog post on working with JMX MBeans.

JMX MBeans are complicated, meaning that careers probably exist for working with JMX MBeans and little else. I’m truly sorry to hear that. For the layperson (and by this, I mean people who work in BI), trying to understand MBeans probably ranks somewhere between getting decent service at a restaurant in the UK, and understanding why the Anomaly needs to join with the Source. It’s complex enough that most vendors provide utilities to simplify the process… which means using anything other than Java to work with them. For Weblogic, we have Weblogic Scripting Tool (WLST).

WLST is really just a specific implementation of Jython designed into a command-line utility that in many ways feels like SQL-Plus or RMAN. It’s designed to work interactively or in scripted fashion, and Rittman Mead has offered up some free WLST scripts to the community over the years via GitHub. If you take a look at our deploy_rpd.py script for example, you can make some sense of how WLST works. I’ve reworked that script slightly in this post to use hardcoded values instead of variables, to remove the exception handling, etc., to make the logic easier to follow. It’s shown here in two parts… the first part which connects to the Weblogic Administration Server and locks the domain:

import sys
import os

connect('weblogic', 'welcome1', 't3://localhost:7001');
domainCustom()
cd ('oracle.biee.admin')
cd ('oracle.biee.admin:type=BIDomain,group=Service')

print 'Locking the configuration...'
objs = jarray.array([], java.lang.Object)
strs = jarray.array([], java.lang.String)
invoke('lock', objs, strs)

This lock method is equivalent to the “Lock and Edit” button inside Fusion Middleware Control. We use the cd command to navigate to the BIDomain MBean because the lock method (as well as commit and rollback ) is in that MBean. The invoke command is used to execute MBean methods in WLST and accept parameters for those methods. To do this we use generic Object and String arrays because the invoke command is generic and needs to support an ever-changing series of parameters. The rest of the pared script is below:

cd ('..')
cd ('oracle.biee.admin:type=BIDomain.BIInstance.ServerConfiguration,biInstance=coreapplication,group=Service')
# Set the parameters
params =  jarray.array(['/mnt/hgfs/stewart/scripts/sugarcrm.rpd','Admin123'],java.lang.Object)
# Set the parameters Signs
sign =  jarray.array(['java.lang.String', 'java.lang.String'],java.lang.String)
# Invoke the procedure
invoke( 'uploadRepository', params, sign)

cd ('..')
cd ('oracle.biee.admin:type=BIDomain,group=Service')
objs = jarray.array([], java.lang.Object)
strs = jarray.array([], java.lang.String)
invoke('commit', objs, strs)

In the second part of this script, we navigate to the ServerConfiguration MBean, which contains the uploadRepository method. We populate the params array with the RPD path and RPD password, we upload the repository, and then navigate back to the BIDomain MBean to perform the commit.

WLST strikes me as an attempt to take a programmatic interface, one that is usually accessed through Java, and make it accessible to non-developers. In this regard, I see it as a major failure. The MBean methods have been abstracted to the point of being almost useless. This seems like the exact opposite of simple to me. It seems overly complex to have to construct arrays and populate them just to pass parameters to methods. I would prefer to just pass parameters as, well… parameters. Additionally… notice how we had to cd to the BIDomain MBean, cd away to go use the ServerConfiguration MBean, and then cd back again. I would prefer to use the MBeans the way they were meant to be used… as objects, so we would be able to instantiate and hold multiple MBean objects at the same time.

If WLST is indeed easier to use than Java, then this is quite an indictment of Java. It works pretty well when we are writing processes that are JMX specific… when the commands that we need to issue are all calls to MBeans and nothing else. But what happens if we want to write a process that involves interacting with MBeans as well as some other processes or APIs, such as calls to any of the Oracle BI Server XML API, in a unified script? WLST is terrible at this. In my first attempt at writing something like this, I used Perl to execute both validaterpd commands as well as MBean commands. I ended up having to maintain a separate Jython script along with the Perl script, which didn’t sit well with me as a developer. What we really need is a language that is groovy to write and maintain, compiles to pure Java (just like Jython), and has the ability to encapsulate MBeans natively in a similar fashion to WLST. What we need is Groovy.

Groovy is a dynamic language that can be used to write scripts, or write object-oriented packages and classes, and can also be used to compile to Java byte code. Because it’s simple to write and has native MBean object handling, it’s easier (in my opinion) than WLST. How easy? Well, let’s go through our deploy_rpd.py example, and see if it’s easier to write and understand. Here’s our upload repository script in Groovy:

import javax.management.remote.JMXConnectorFactory
import javax.management.remote.JMXServiceURL
import javax.naming.Context

def h = new Hashtable()
h.put(Context.SECURITY_PRINCIPAL, 'weblogic')
h.put(Context.SECURITY_CREDENTIALS, 'welcome1')
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote")
jmxConnector = JMXConnectorFactory.connect(new JMXServiceURL("service:jmx:t3://localhost:7001/jndi/weblogic.management.mbeanservers.domainruntime"), h)
server = jmxConnector.getMBeanServerConnection()

def biDomain = new GroovyMBean(server,'oracle.biee.admin:type=BIDomain,group=Service')
def servConfig = new GroovyMBean(server, 'oracle.biee.admin:type=BIDomain.BIInstance.ServerConfiguration,biInstance=coreapplication,group=Service')

biDomain.lock()
servConfig.uploadRepository('/mnt/hgfs/stewart/scripts/sugarcrm.rpd', 'Admin123')
biDomain.commit()

That’s the whole script. There’s a few things to point out here. First… establishing connectivity to the Weblogic Admin Server is slightly harder in Groovy. WLST hides a good bit of the complexity with connectivity, but the JMXConnectorFactory class in Groovy is a close second. However, once the connectivity is done, Groovy wins the rest of the way. Notice how we are able to configure two different MBean objects: biDomain for BIDomain and servConfig for ServerConfiguration. We don’t have to cd back and forth across the MBean hierarchy to work with the different MBeans; we can simply instantiate as many MBeans at once as we need to.  Also, notice that we don’t have the generic invoke command to call the different methods in MBeans. We just call the method directly: if we want to call lock(), or commit(), or uploadRepository(), we just call it, and pass the parameters that it accepts. No need to build the generic Object and String arrays for passing in to invoke.

Because Groovy is very easy to execute external command-line processes (such as biserverxmlexec or biserverxmlgen) it’s a great choice for unified OBIEE processes that need to work with executables and JMX MBeans together in a single script. Also… Groovy accepts Java syntax, so if we can’t find the Groovy code samples we need from the internet, we can just plug in Java samples instead.