A Very Useful Tool for Cognos Admins

MotioPI is a great (free) tool for Cognos Administrators.   If you are responsible for one or more Cognos environments, I highly recommend it.     In short, its designed to provide Cognos administrators an easy way to gain insight into the content and configuration in their content store.   

For example – you can quickly Find all Schedules associated with a given area of your content store,  Batch Validate a series of Cognos Reports, or quickly snapshot your various Cognos administrative settings (dispatchers, report services, etc.).

Note – by and large, the free version of MotioPI is read-only, the one exception being the Orphaned Objects panel – which lets you re-assign Cognos  content (e.g. My Folders data) to another user.   

Motio also has a professional version which lets you do mass updates to Cognos content / configuration (e.g. search and replace across many reports, bulk management of user preferences / group memberships, replicate properties across many Cognos objects, etc.).

I think Google is going to take a serious bite out of Apple…

Part of me wonders if we’ve seen a “local maximum” on Apple.

I think their escalating rivalry with Google is going to really hurt them in the long run. Here are some of the key fronts in my opinion.

The Android Platform : Google’s Android mobile operating system is the open source platform behind many smart phone competitors to the iPhone. It’s also starting to show up in other non-phone devices like netbooks and the Barnes and Nobles Nook (E-Reader).

Android is an open platform, being used on a wide variety of devices, with backing from a diverse ecosystem of contributors. Apple’s iPhone is a closed and tightly controlled platform being developed by one company (some might throw out a Linux vs. Windows analogy).

One perspective which I find a bit ironic : By giving smart phone providers a rich, stable core to build upon, Android should free them up to focus more on consumer oriented features (rather than expending huge amounts of effort on OS level plumbing). From the smart phone provider perspective, isn’t this kind of similar to how Apple leveraged a solid BSD Unix based core to build the very consumer friendly OS X…?

It will be interesting to watch the evolution of these two platforms in the coming years. One might speculate that the diverse ecosystem leveraging Android may drive more innovation.

Google’s Online Music Service : There’s widespread speculation that Google is launching an Online Music Service which will compete with iTunes.

Maybe its just me, but it seems like consumers have a lot of pent up animosity at Apple over iTunes. iTunes has pissed off users for years (try googling for I hate iTunes and marvel at the number of results).

Personally – iTunes drives me nuts, but I’m stuck with it (I have an iPhone). Over the years, it has lost my music, made it difficult for me to share music I purchased across multiple devices, refused to read metadata on music I imported via non-iTunes software, etc.

iTunes is at version 9. Its been around for years and has a huge user base. There’s no reason why Apple shouldn’t have fixed many (if not all) of these issues. Certainly there’s been lots of feedback – maybe its fallen on deaf ears.

Apple will no doubt continue to be the dominant player in online music sales, but it can’t be good that a company with Google’s clout and reputation is getting ready to compete with them in this space. I think their window for easy money in digital media distribution is shrinking.

Public Opinion : Maybe its just me, but it seems tide of public opinion regarding Apple is starting to turn a bit. For years they have been the cool, innovative underdog. At times they now seem more like a condescending incumbent.

For example – consider their draconian rejection policies for third party applications submitted to the iTunes App Store. As a developer, I can tell you I would be absolutely done with Apple if I worked my tail off on an iPhone App for months only to have them reject it with basically a “because we said so” response. This will most certainly drive innovative app developers away from Apple (and to a more open model).

From a PR perspective, this sort of thing is a certainly a black eye for Apple.

Contrast this with the current public love affair with Google and their “Do No Evil” branding, and I think Google is poised score points vs. Apple in the court of public opinion.


Since the above is largely opinion – I thought I’d add a bit about myself : I am not an Apple fanboy or an Apple hater. I own machines with OSX (macbook), XP (netbook) and Ubuntu (primarly laptop) on them. I’m now on my second iPhone (I’ve had a first gen and a 3GS), and I’ve not yet owned an Android based phone. I have yet to develop any iPhone or Android based apps. I don’t own any Google or Apple stock. In short – I have no bones to pick with Apple, these are just observations.

A way to get true Symbolic Links on Windows…

Its always really annoyed me that Windows “shortcuts” to folders don’t truly behave like Unix / Linux symbolic links. I’ve been especially annoyed by this recently, since I’ve been forced to use Outlook Web Access for one of my clients, and when you try to attach a file to an email message in OWA, if you try to navigate through a shortcut to a folder, rather than actually navigate to the target folder it will “attach” the shortcut to the message. Sigh…

I just realized that the sysinternals suite has a utility called Junction which will let you create a true symbolic link to a directory on Windows. Sweet!

I have always been very fond of the sysinternals tools… Process Explorer and Tcpview are probably the ones I’ve gotten the most mileage out of. Many thanks to Mark Russinovich for this excellent suite of utilities.

Oracle: Difference between two Timestamps, in seconds…

In oracle, if you subtract two timestamps, the result is of type “interval”. Its somewhat cumbersome to get the total number of seconds this interval represents. Here’s an Oracle function which will yield the total number of seconds between two timestamps :

CREATE OR REPLACE function timestamp_diff_in_seconds (ts1 in timestamp, ts2 in timestamp)
       return number is total_secs number;
       diff interval day(9) to second(6);
   diff := ts2 - ts1;
   total_secs := abs(extract(second from diff) + extract(minute from diff)*60 + extract(hour from diff)*60*60 + extract(day from diff)*24*60*60);

   return total_secs;
end timestamp_diff_in_seconds;

Using the above, we can get the toal time in seconds, between two timestamp parameters (effectively converts the “interval” difference of the two timestamps into to the total number of seconds)

XP Tip: “right-click on file and send-to cygwin tail”

During a typical “development” day, there are many times when I want to “start a tail” on some arbitrary log file. Wouldn’t it be nice if you could just right-click on a file in Windows Explorer and start a tail on it…? Here’s how.

First, we create a simple 1 line batch file called “startTailOn.cmd”. The batch file will expect a single parameter (the path to the file).

      start "tail on %1" c:\dev\cygwin\bin\tail.exe -n 1000 -f %1

This batch file simply starts a new command prompt with a title of “tail on “, and then executes the cygwin tail command on the specified file.

Now we just need to add a shortcut to our batch file to our Windows “send to” menu (shown when you right click on a item in Windows Explorer). To add a new action to your “send to”, you just need to add a shortcut to the action in the SendTo folder in your home directory (e.g. mine is at C:\Documents and Settings\lhankins\SendTo).

So in keeping with our earlier example, we’ll add a shortcut here to our “startTailOn.cmd” file (as depicted below).

add shortcut on sendto

Note – you can rename the default shortcut name of “Shortcut to startTailOn.cmd” to just “tail”.

That’s it. Now suppose we right click on d:\temp\boot.log and select our new “send to tail” action :

tail on log

The only shortcoming here is that the batch file we created will barf if the path to the in question has spaces in it (the part that fails is the ‘window title’ argument to the ‘start’ command). I generally keep a second batch file on my SendTo menu to handle these cases, e.g. “startTailOnPathWithSpaces.cmd”.

   start "tail" c:\dev\cygwin\bin\tail.exe -f %1

More Readable Classpaths for Ant Builds…

Its always a bit painful when you hit the inevitable ClassNotFound exception during development and you end up double checking an Ant classpath variable against the jars you think should be there. The way I typically debug this is to assign the particular ant classpath to a property, then echo the property value, e.g. :

<property name="current.classpath" refid="dao.compile.classpath"/>
<echo level="info" message="current.classpath=${current.classpath}"/>

Which will end up producing hard to read output that looks something like this (a big, semicolon delimited list of jars) :

[echo] current.classpath=d:\work\proto\dist\foo-toolkit.jar;d:\work\proto\lib\hibernate-2.1.8\lib\dom4j-.4.jar;d:\work\proto\lib\commons-discovery-0.2\commons-discovery.jar;d:\work\proto\lib\hibernate-.1.8\hibernate2.jar;d:\work\proto\lib\hibernate-2.1.8\lib\c3p0-;d:\work\proto\lib\hibernate-2.1.8\lib\cglib-full-2.0.2.jar;d:\work\proto\lib\hibernate-2.1.8\lib\ehcache-0.9.jar;d:\work\proto\lib\hibernate-2.1.8\lib\jta.jar;d:\work\proto\lib\hibernate-2.1.8\lib\odmg-3.0.jar;d:\work\proto\lib\hibernate-2.1.8\lib\oscache-2.0.jar;d:\work\proto\lib\hibernate-2.1.8\lib\swarmcache-1.0rc2.jar;d:\work\proto\lib\oracle-10g\classes12-10g.jar;d:\work\proto\lib\jakarta-struts-1.2.4\lib\commons-beanutils.jar;d:\work\proto\lib\commons-lang-2.0\commons-lang.jar;d:\work\proto\build\dao\classes;d:\work\proto\lib\jakarta-struts-1.2.4\lib\commons-logging.jar;d:\work\proto\lib\commons-collections-3.1\commons-collections.jar;d:\work\proto\lib\commons-io-1.0\commons-io.jar;d:\work\proto\lib\commons-dbutils-1.0\commons-dbutils.jar;d:\work\proto\lib\spring-1.2\acegi-security-0.8.2.jar;d:\work\proto\lib\spring-1.2\commons-codec.jar;d:\work\proto\lib\spring-1.2\ehcache-1.1.jar;d:\work\proto\lib\spring-1.2\spring-aop.jar;d:\work\proto\lib\spring-1.2\spring-beans.jar;d:\work\proto\lib\spring-1.2\spring-context.jar;d:\work\proto\lib\spring-1.2\spring-core.jar;d:\work\proto\lib\spring-1.2\spring-dao.jar;d:\work\proto\lib\spring-1.2\spring-hibernate.jar;d:\work\proto\lib\spring-1.2\spring-jdbc.jar;d:\work\proto\lib\spring-1.2\spring-mock.jar;d:\work\proto\lib\spring-1.2\spring-orm.jar;d:\work\proto\lib\spring-1.2\spring-remoting.jar;d:\work\proto\lib\spring-1.2\spring-support.jar;d:\work\proto\lib\spring-1.2\spring-web.jar;d:\work\proto\lib\spring-1.2\spring-webmvc.jar;d:\work\proto\lib\spring-1.2\spring.jar;d:\work\proto\lib\util.concurrent-1.0\util.concurrent.jar

That format gets a little painful to scan with the human eye, since all the paths typically begin with the same root. So here’s a better way to do this : We’ll use the ant task to replace the semicolons in our debug variable with a newline and some whitespace.

<property name="current.classpath" refid="dao.compile.classpath"/>

<propertyregex property="current.classpath"

<echo level="info">
   Classpath is :


Now when we run the aforementioned Ant snippet, it will produce the following output (much easier on the eyes) :

[echo] d:\work\proto\dist\foo-toolkit.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\dom4j-1.4.jar
[echo] d:\work\proto\lib\commons-discovery-0.2\commons-discovery.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\hibernate2.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\c3p0-
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\cglib-full-2.0.2.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\ehcache-0.9.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\jta.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\odmg-3.0.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\oscache-2.0.jar
[echo] d:\work\proto\lib\hibernate-2.1.8\lib\swarmcache-1.0rc2.jar
[echo] d:\work\proto\lib\oracle-10g\classes12-10g.jar
[echo] d:\work\proto\lib\jakarta-struts-1.2.4\lib\commons-beanutils.jar
[echo] d:\work\proto\lib\commons-lang-2.0\commons-lang.jar
[echo] d:\work\proto\build\dao\classes
[echo] d:\work\proto\lib\jakarta-struts-1.2.4\lib\commons-logging.jar
[echo] d:\work\proto\lib\commons-collections-3.1\commons-collections.jar
[echo] d:\work\proto\lib\commons-io-1.0\commons-io.jar
[echo] d:\work\proto\lib\commons-dbutils-1.0\commons-dbutils.jar
[echo] d:\work\proto\lib\spring-1.2\acegi-security-0.8.2.jar
[echo] d:\work\proto\lib\spring-1.2\commons-codec.jar
[echo] d:\work\proto\lib\spring-1.2\ehcache-1.1.jar
[echo] d:\work\proto\lib\spring-1.2\spring-aop.jar
[echo] d:\work\proto\lib\spring-1.2\spring-beans.jar
[echo] d:\work\proto\lib\spring-1.2\spring-context.jar
[echo] d:\work\proto\lib\spring-1.2\spring-core.jar
[echo] d:\work\proto\lib\spring-1.2\spring-dao.jar
[echo] d:\work\proto\lib\spring-1.2\spring-hibernate.jar
[echo] d:\work\proto\lib\spring-1.2\spring-jdbc.jar
[echo] d:\work\proto\lib\spring-1.2\spring-mock.jar
[echo] d:\work\proto\lib\spring-1.2\spring-orm.jar
[echo] d:\work\proto\lib\spring-1.2\spring-remoting.jar
[echo] d:\work\proto\lib\spring-1.2\spring-support.jar
[echo] d:\work\proto\lib\spring-1.2\spring-web.jar
[echo] d:\work\proto\lib\spring-1.2\spring-webmvc.jar
[echo] d:\work\proto\lib\spring-1.2\spring.jar
[echo] d:\work\proto\lib\util.concurrent-1.0\util.concurrent.jar

Subtle Difference Between JavaScript Evaluation in IE vs. Firefox…

I came across an annoying difference between the way IE and Firefox interpret JavaScript array lengths. Consider the following snippet:

var a1 = [1,2,3,4];
var a2 = [1,2,3,4,];

alert("a1.length = [" + a1.length + "], a2.length = [" + a2.length + "]");

So basically the only difference between a1 and a2 is that a2 has a trailing comma at the end of the array initializer (legal in both Java and JavaScript). Anyway, in Firefox, the lengths of these two arrays are the same (as I would expect), the alert evaluates to :

a1.length = [4], a2.length = [4]

In IE, however, the lengths are different (it actually increases the size of the array for the trailing comma – <sigh>)

a1.length = [4], a2.length = [5]