This post might alternately be titled, “So you’re really stubborn and wasted a couple of hours messing with the Essbase Java API”, or something. I was in a discussion the other day and asked about the ability to run an application-level calc script.
Well, back up, actually. Did you know that calc scripts can exist at the application level in Essbase? For a very long time, Essbase has had this notion of applications and databases (with databases often just being called cubes), such that there is usually one database/cube inside of an application, but there can technically be more (at least in the case of BSO). It’s almost always the best practice to have just one cube to an application. This is largely for technical reasons.
That said, while objects like load rules and calc scripts typically exist within the folder for a given cube, they can technically be located inside of the application itself. In theory you might want to have a calculation script that is applicable to multiple cubes in an app, and would want to centralize it in the application. Here’s a screenshot of the Sample app showing that there is, indeed, a calculation script located in it (that I have placed there);
The most generous thing I can think to say about application-level objects like calc scripts and load rules is that they are essentially a vestigial organizational paradigm from yesteryear. While Oracle hasn’t gone out of their way to prohibit their use, they haven’t gotten any love (nor would they necessarily warrant it). You can’t create them directly in EAS (you can copy an existing script from a cube, which is what I did for the above screenshot). You can’t run them from Smart View. I don’t believe there is a way to grant access to them from Shared Services (cube level calcs, no problem).
You can technically run them using MaxL and run them from EAS.
What you can’t do, however, is run them using the Essbase Java API. That’s where this post comes in. I was really wondering if it was possible to run an app-level calc using the the Java API. But there’s no method for it. The typical method you’d use is calculate()
on an IEssCube
interface. But there’s no equivalent method for an IEssOlapApplication
. Usually you pass a calc script name to the calculate()
method, but you can’t try and trick it with a relative folder path or pass in null or something.
However, the old C API for Essbase could run an app-level calc. It turns out there’s a function there that can take null for the cube parameter and will just assume the calc lives in the app.
Surely, I thought, there’s a way to make this happen or maybe trick the Java API into doing my bidding for me. I thought that maybe if I could get the Essbase Java API to pass a null cube name in for me, I could maybe trick it. I took a look at the bytecode (compiled files in the Essbase Java API) and found that it’d be impossible, actually, to try and supply an arbitrary cube name to the calculation function, because of the way that it reads the cube name from the class itself.
That said, there appears to be a very dirty/hacky way to trick the IEssCube implementation into passing a null value in and getting the underlying C API function to execute the app-level calc.
The trick is to subclass EssCube (the implementing class for IEssCube) and selectively override a couple of methods so that when the calculation method is invoked, it reads our fake cube name of null, then executes the calc.
Anyway, here’s a GitHub Gist with the sample files for tricking the Java API into running an app-level calc. The real trick is to allow for specifying a fake name as well as also overriding the setActive() method that is called internally int the Essbase Java API so that it doesn’t just blow out the fake value we’re supplying.
So, when would you use this? The answer is never. You should never, ever, ever do this. It’s using a private API class (bad!), to facilitate a functionality that is of marginal usefulness in the first place, is rarely used, and isn’t getting much support.
Nevertheless, in some ways it’s an interesting example of being stubborn hacking an API to try and do your bidding when the out of the box functionality isn’t quite sufficient.
Interesting post but I will classify it in Geekery-keepItForLater category! Ok fun category is alright!
Once in the past, when I had free time to waste at nights, I investigated a way to create a Java function to do calc scripts inclusion. The real challenge was to build an include cdf without specifying user or pwd – I failed concerning the no usr/pwd requirement, I guess you wouldn’t have this kind of hack in you keepItForLater box?
Hi Sébastien,
The most common solution I see for what you are describing is to encode the password and use that inside the calc script. Alternatively you might set it up to reference a specific file on the server filesystem but you’d want that to be encoded as well. I don’t have a specific example but you could take some inspiration from some of the encrypted MaxL commands in Planning.