Welcome to bexhuff.com

This is the professional blog for me, Brian 'Bex' Huff. My writing covers science, lifehacks, and computers. I spend a good amount of time on Oracle Fusion Middleware -- which includes the Enterprise Content Management (ECM) technology Oracle purchased from Stellent...

Be sure to check out my book on Oracle Enterprise Content Management (ECM), my Oracle specific posts, or visit the sponsor Bezzotech -- my Oracle UCM consulting firm. There's plenty of free presentations and components if you're interested...

2011 Blog Year-In-Review!

I'm continuing my tradition of doing my blog year-in-review in late April... mainly because I started my blog six years ago on April 29th. But, also in the hopes it would stand out more, since everybody else has a fiscal-blog-year-end on December 31st!

In the 2011/2012 time frame I had 204,514 page views, which is a 12% increase over the previous year! Woah... surprised to see that spike, considering I've been feeling guilty about not posting enough these days... altho a lot of that was because my post on how Steve Jobs couldn't program a computer was on the front page of Hacker News for a few days! The top posts from 2011 are as follows:

  1. Oracle Acquires FatWire! And people are curious as to what will happen next...
  2. Oracle Mix Jumped The Shark: a rant against how some folks rigged the Mix system to con their way into getting Open World Sessions. Uncool.
  3. WebCenter Performance Tuning: a case study in WebCenter Content tuning
  4. WebCenter 11g PatchSet5: some useful downloads and links
  5. One WebCenter To Rule Them All: some coverage of the rebranding that occurred at OpenWorld 2011
  6. Collaborate 2011 Presentations: always good stuff there ;-)
  7. Mashup Standards: JSON-P Versus CORS! My opinions on why JSON-P is superior, and an add-on to my popular jQuery Plugin to better support mashups
  8. PowerPoint Tips From South Park: the title says it all...
  9. More On FatWire: additional analysis and predictions
  10. Multilingual UCM: some info on how to support multiple languages with UCM

This year I should have time to add more tutorials... there's some nifty stuff coming out in the next version of WebCenter that could change how people do enterprise integrations. Stay tuned...

FatWire Tutorial for Site Studio Developers

Oracle recently acquired FatWire, and renamed it WebCenter Sites. It is a "web experience management" toolkit, which is similar to Oracle's existing Site Studio product -- a part of Oracle UCM, now called WebCenter Content.

After using Site Studio for years, I got pretty accustomed to it's terminology and toolkits... so looking at FatWire was initially intimidating because it was just so dang different. But, after using it for several months, I've come to the conclusion that a lot of the fundamentals are pretty similar. Pretty much everything Site Studio does is built in to FatWire, and FatWire has a few nifty extras as well.

So, for IOUG Collaborate this year, I put my insights together into a presentation: Crash Course in FatWire for Site Studio Developers:

It's not a replacement for actual training... but it does cover all the major low-level assets, and how they fit together to form a site. If you know a thing or two about Site Studio, this should help you get over the initial "fear of the unknown!"

Even More WebCenter Translation Capabilities!

Last year we released a translation connector for WebCenter Content, with our partner Lingotek. This year, that translation power has also been extended to WebCenter Sites (formerly FatWire).

WebCenter sites has out-of-the-box support for translated assets, called dimension sets, which was easy to plug-in to the Lingotek Platform. This connector also engages the community in that people can not only access translated content, but they can recommend content for translation, or even translate the content themselves! That's a pretty handy capability for community-centric web sites...

If you'd like to see more, Lingotek is doing a demo next Tuesday, April 17th, 10am EST. Be sure to register first!

Countdown to Collaborate 2012!

It's that time of year again! The biggest Oracle user conference is nearly upon us... IOUG Collaborate 2012, from Sunday, April 22 through Thursday April 26. This year, my company Bezzotech is sponsoring the Sunday WebCenter "Deep Dive". The deep dive covers Content, Sites, Social, and of course Portal!

We'll be at Booth #1179 right on Main Street, near the Oracle Demo Pods. We are also presenting seven sessions on WebCenter and ADF:

  • Sunday, 4:30pm: The Fusion Applications User Experience: Transforming Work into Insight
  • Monday, 1:15pm: WebCenter Content, WebCenter Spaces, WebCenter Sites, which is right for me?
  • Monday, 1:15pm: How to save physical storage with Oracle UCM
  • Monday, 3:45pm: Upgrading to IPM 11g, where do I start?
  • Tuesday, 10:45am: Crash Course In WebCenter Sites (FatWire) for Site Studio Customers
  • Wednesday, 9:30am: HOW TO SAVE $20 MILLION PER YEAR WITH ORACLE UCM
  • Thursday, 9:45am: Making Next-Generation Mobile Apps With The Latest ADF Mobile Tools

Dang! Lots of presentations to give this year... so if you don't find us on stage, or hanging out near the WebCenter session rooms, swing by our booth! Or, feel free to tweet me ;-)

Daylight Savings Time... Again?!?!

It's tough explaining why we have Daylight Savings Time... it's really tough explaining why we have it to a grumpy 4-month old who wants to keep napping... it's really, really tough explaining why we have it the same week it snows in Seattle fer crying out loud... Frankly, I think we should do away with it, and C. P. G. Grey agrees with me:

He's not alone... several academic studies have shown that daylight savings time wastes money and kills people. People use light bulbs less, but air conditioning more, so energy savings is non-existent. Also, there's a higher incident of car crashes, accidents, and heart attacks because everybody is sleepy and stressed out.

I'm for getting rid of it... how about you?

Downloads For Oracle WebCenter Content (UCM) 11g Patch Set 5

Oracle UCM Patch Set 5 is released! And thus begins the long, long hunt for the patches you need to upgrade...

Most of this info is available in the Oracle FAQ for ECM 11g, as well as the Oracle Fusion Middleware Patching Guide... but I was tired of it being un-googleable... So I decided to put a few of the links together here.

Upgrading ECM can be a multi-step process. You need to upgrade WebLogic before upgrading ECM, and you need to make sure you have the right version of the Repository Creation Utility (RCU)... not to mention the multi-gigabyte general installer for ECM itself (which includes IPM, UCM, IRM, and URM). If it's a new install, just grab the most recent Weblogic Server downloads. Otherwise, use the upgrade installers below:

Patch Set 3

Patch Set 4

Patch Set 5

And yes, in case you noticed, I'm using those nifty short URL for Oracle patches I set up... makes the URLs a lot easier to digest, don't ya think?

Shorter URLs for Oracle Patches

How many times has this happened to you???

You're looking around Oracle for the latest patches, and after copious amounts of digging, you finally find the mystery patch that you need... you click on the "download" link, install it, and you're good to go!

Later on... your client, or co-worker, or somebody on the message board asks, "How'd you do that?" And because you have a photographic memory, you reply "With patch 12395560, of course!" Then they ask, "got a link?" And then you say this:

https://support.oracle.com/CSP/ui/flash.html#tab=PatchHomePage(page=PatchHomePa
ge&id=gj46o799()),(page=PatchSearchResultsHome&id=gj46pr1y(search=%3CSearch%3E%
0A%20%20%3CFilter%20name=%22patch_number%22%20op=%22IS%22%20value=%2212395560%2
2%20type=%22patch_number%22/%3E%0A%20%20%3CFilter%20name=%22platform%22%20op=%2
2IS%22%20value=%22%22%20type=%22platform%22/%3E%0A%3C/Search%3E&incFamilyProds=
false&flag=search))

Yikes... not exactly 'twitter friendly.'

In order to simplify the process (and make my documentation more readable), I set up a URL Shortener for Oracle patches for myself. Unlike most URL shorteners, it takes a parameter. The number after the slash is the Oracle patch number... which should be easy to spot on the form. So, instead of the crazy URL above, you could use one of these two:

http://para.ms/ora-patch/12395560
http://para.ms/oracle-patch/12395560

The first one goes to the standard My Oracle Support page -- with all it's flashy goodness -- and gets as close to a "quick-link" that I could deduce. The second URL goes to the old fashioned Oracle Updates web site, which supports parameterized URL quite nicely. Guess which one I prefer? ;-)

Ideally, the Oracle support team would implement a parameter-based redirect themselves... and expose that "quick link" on the support page. Until then, I'm going to do it this way. I wonder if it will catch on???

Quick Links

For your consideration...

  • Oracle Patches:
    http://para.ms/oracle-patch/
  • Oracle Bugs:
    http://para.ms/oracle-bug/

Mashup Standards Part 3: JSONP versus CORS

In part 1 of this post, I covered the JSON-P "standard" for mashups. Not so much a standard per se, but a sneaky way to share JSON code between servers by wrapping them in a 'callback' function... For example, if we have our raw JSON data at this URL:

http://example.com/data.js

A direct access would return the raw data dump in JSON format:

{ foo: "FOO", bar: "BAR" }

However, a JSON-P call would return a JavaScript file, that calls a 'callback' function with the raw data:

callback({ foo: "FOO", bar: "BAR" });

Since this is pure JavaScript, we can use it to bypass the "Same-Origin Policy" for AJAX... A typical AJAX call uses the XmlHttpRequest object, which only allows calls back to the originating server... which, of course, means true mashups are impossible. JSON-P is one of the (many) ways around this limitation.

Since JSON-P is something of a hack, many developers started looking for a more secure standard for sharing JSON and XML resources between web sites. They came up with Cross-Origin Resource Sharing, or CORS for short. Enabling CORS is as simple as passing this HTTP header in your XML/JSON resources:

Access-Control-Allow-Origin: *

Then, any website on the planet would be able to access your XML/JSON resources using the standard XmlHttpRequest object for AJAX. Despite the fact that I like where CORS is going, and see it as the future, I just cannot recommend CORS at this point.

Security

Since CORS is built on top of the XmlHttpRequest object, it has much nicer error handling. If the server is down, you can recover from the error and display a message to the user immediately. If you use JSON-P, you can't access the HTTP error code... so you have to roll-your-own error handling. Also, since CORS is a standard, it's pretty easy to just put a HTTP header in all your responses to enable it.

My big problem with CORS comes from the fact that it just doesn't seem that well supported yet... Only modern browsers understand it, and cross-domain authentication seems to be a bit broken everywhere. If you wanted to get secure or personalized JSON on a mashup, your back-end applications will need to also set this HTTP header:

Access-Control-Allow-Credentials: true

And, in theory, the AJAX request will pass along your credentials, and get back personalized data. The 1.7 jQuery plug-ins works well with JSON-P and authentication, but chokes badly on CORS. Also, keep in mind that authenticated CORS is a royal pain in Internet Explorer. Your end users will have to lower their security setting for the entire mashup application in order to make authenticated requests.

Now, JSON-P isn't great with security, either. Whereas CORS is too restrictive, JSON-P is too permissive. If you enable JSON-P, then you pass auth credentials to the back-end server with every request. This may not be a concern for public content, but if an evil web site can trick you into going to their mashup instead of your normal mashup, they can steal information with your credentials. This is call Cross-Site Request Forgery, and is a a general security problem with Web 2.0 applications... and JSON-P is one more way to take advantage of any security holes you may have.

Performance

In addition, the whole CORS process seems a bit 'chatty.' Whereas JSON-P requires one HTTP request to get secure data, CORS requires three requests. For example, assume we had two CORS enabled applications (app1 and app2) and we'd like to blend the data together on a mashup. Here's the process for connecting to app1 via CORS and AJAX:

  1. Pre-Flight Request: round-trip from client browser to app1 as a HTTP 'OPTIONS' request, to see if CORS is enabled between mashup and app1
  2. Request: if CORS is enabled, the browser then sends a request to app1, which sends back an 'access denied' response.
  3. Authenticated Request: if cross-origin authentication is enabled, data is sent a third time, along with the proper auth headers, and hopefully a real response comes back!

That's three HTTP requests for CORS compared to one by JSON-P. Also, there's a lot of magic in step 3: will it send back all the auth headers? What about cookies? There are ways to speed up the process, including a whole ton of good ideas for CORS extensions, but these appear to be currently unpopular.

Conclusion: Use JSON-P With Seatbelts

If all you care about is public content, then CORS will work fine. Also, it's a 5-minute configuration setting on your web server... so it's a breeze to turn on and let your users create mashups at their leisure. If you don't create the mashups yourself, this is sufficient.

However... if you wish to do anything remotely interesting or complex, JSON-P has much more power, and fewer restrictions. But, for security reasons, on the server side I'd recommend a few safety features:

  • Validate the HTTP_REFERER: only allow JSON-P requests from trusted mashup servers, to minimize request forgery.
  • Make JSON-P requests read-only: don't allow create/modify/delete through JSON-P.

But wait, isn't it easy to spoof the HTTP referrer? Yes, an evil client can spoof the value of the referrer, but not an evil server. In order for an evil mashup to spoof the referer, he'd have to trick the innocent user to download and run a signed Applet , or something similar. This is a typical trojan horse attack, and if you fall for it, you got bigger problems that fancy AJAX attack vectors... DNS rebinding is much more dangerous, and is possible with any AJAX application: regardless of JSON-P or CORS support.

Links and Free Downloads

For those of you interested in Oracle WebCenter, I created a CrossDomainJson component that enables both CORS and JSON-P, and it includes some sample code and documentation for how to use it. It currently works with WebCenter Content, but I might expand it to include WebCenter Spaces, if I see any interest.

Meet Me in Toronto on Thursday!

For those of you in the Toronto area, I'll be presenting at the AIIM/Oracle Social Business Seminar this Thursday! Its at Ruth's Chris Steakhouse, 145 Richmond Street West, Toronto, ON. The agenda is as follows:

  • 10:00 a.m: How Social Business Is Driving Innovation, Presented by: John Mancini, AIIM
  • 11:00 a.m: Solving the Innovation Challenge with Oracle WebCenter, Presented by: Howard Beader, Oracle
  • 12:00 noon: Lunch and Networking, Table Discussions on Case Study Challenges
  • 1:00 p.m: Strategies for Success Case Study, Presented by Bex Huff, Bezzotech
  • 1:45 p.m: Final Remarks

Space is limited, so register now for a seat!

Mashup Standards Part 2: Cross-Origin Resource Sharing (CORS)

In my previous post, I was talking about the JSON-P standard for mashups. It's very handy, but more of a "convention" than a true standard... Nevertheless, it's very popular, including support in jQuery and Twitter. In this post I'm going to discuss what some consider to be the modern alternative to JSON-P: Cross-Origin Resource Sharing, or CORS for short.

Lets say you had two applications, running at app1.example.com and app2.example.com. They both support AJAX requests, but of course, they are limited to the "Same-Origin Policy." This means app1 can make AJAX requests to app1, but not to app2. Let's further assume that you'd like to make a mashup of these two app at mashup.example.com.

No problem! In order to enable cross-origin AJAX, you simply need to make sure app1 and app2 send back AJAX requests with this HTTP header:

Access-Control-Allow-Origin: http://mashup.example.com

This is easily done, by adding one line to the Apache httpd.conf file on app1 and app2:

Header set Access-Control-Allow-Origin http://mashup.example.com

DONE! Now, with standard AJAX calls you can host a HTML page on mashup.example.com and connect to app1> and app2 using nothing but JavaScript! There are about a half dozen additional Cross-origin HTTP header that you can set... including what methods are allowed (GET/POST), how long to cache the data, and how to deal with credentials in the request... naturally, not all browsers support all headers, so your mileage may vary!

Not to mention, because the XmlHttpObject is used, CORS has much better error handling than JSON-P. If there's an error accessing a file, you can catch that error, and warn the end user. Contract that with JSON-P, where there's no built-in way to know when you can't access a file. You can build your own error handling, but there's no standard.

Nevertheless, I still prefer JSON-P for mashups. Why? Well, it boils down to two things: performance, and security. I'll be covering the specifics in part 3 of this port.

Mashup Standards Part 1: JSON-P

In a recent project, I had a client who wanted to resurface Oracle UCM content on another web page. The normal process would be to use some back-end technology -- like SOAP, CIS, or RIDC -- to make the connection. But, as a lark, I thought it would be more fun to do this purely as a mashup. I would need to tweak UCM to be more "mashup-friendly" -- I'll be sharing the code (eventually) -- but first I needed to do some research on the best mashup "standard" out there.

UCM supports JSON, but that's not enough for a true mashup. The problem is that even though UCM can send back JSON encoded responses, you cannot access this data from a different web page. This is because of the "Same-Origin Policy" in AJAX. Basically, you can make an AJAX call back to the originating server, but you cannot make it to a different server. This is quite annoying, because then you can't "mash-up" UCM content onto another web page using just JavaScript. The best mashup APIs -- like Google Maps -- can't use AJAX because of this limitation.

Many developers consider this 'security' feature quite odd, because it's totally okie-kosher to include JavaScript from other people's web sites... so why not AJAX? Knowing full well that this was kind of stupid, some developers came up with a 'convention' for fixing it: "padded JSON," or JSON-P. This means 'padding' a standard JSON response with a callback, and then calling that callback function with the response. For example, if you called the PING_SERVER service with JSON enabled, with a URL like so:

http://example.com/idc/idcplg?IdcService=PING_SERVER&IsJson=1

You would get back the following JavaScript response:

{ LocalData: { StatusMessage: "You are logged in as sysadmin", StatusCode: 1} }

You would then use the standard AJAX XmlHttpResponse object, parse this JSON data, then do something with the message. My jQuery Plugin for UCM does exactly this... but of course has the limitation that it will only work on HTML pages served up by UCM. You can use fancy proxies to bypass this limitation, but it's a pain.

Instead, if UCM supported 'padded JSON', the process would be different. The URL would look something like this:

http://example.com/idc/idcplg?IdcService=PING_SERVER&IsJson=1&callback=processData

And the JavaScript would instead look like this:

processData({ LocalData: { StatusMessage: "You are logged in as sysadmin", StatusCode: 1} });

In this case, the callback=processData parameter triggers the server to 'wrap' the JSON response into a call to the function processData. Then, instead of using the XmlHttpResponse object, you'd use good old-fashioned remote scripting. Like so:

function pingServer() { var url = "http://example.com/idc/idcplg?IdcService=PING_SERVER&IsJson=1&callback=processData" var scriptNode = document.createElement("script"); scriptNode.src = url; document.body.appendChild(scriptNode); } function processData(ucmResponse) { var msg = ucmResponse.LocalData.StatusMessage; alert(msg); }

Notice how we define a function on the page called 'processData.' When the UCM response returns, it will call that function with our response data. The beauty here is that you can put this JavaScript on any web page in your enterprise, and connect directly with UCM with nothing but JavaScript. Pretty nifty, eh?

Now... JSONP is a good idea, but it's about 5 years old... A lot of newer browsers support a slightly different standard: Cross-Origin Resource Sharing. It's an actual standard, unlike JSON-P which is more of a convention... the purpose is to safely allow some site to violate the silly "Same-Origin Policy". I'll be covering CORS in part 2 of this post, including the security enhancement. But, in part 3 I'll explain why I still prefer JSON-P, provided you add some extra security.

2011, and the Decade to Follow

I knew that 2011 was a big year... but not until I saw the video above did I realize that so many events that will shape the decade to come all occured in the same year:

  • Tsunamis and nuclear disasters in Japan
  • Extreme weather worldwide
  • Revolutions in Egypt, Tunisia, and Libya
  • Rumblings of revolutions in Syria, Yemen, and Iran
  • Near economic collapse of the Euro zone, including riots in Greece
  • The death of three monsters: Osama Bin Laden, Gaddafi, and Kim Jong Il
  • The 99% 'Occupy' movement throughout Western countries
  • The passing of Steve Jobs

And countless other events and ideas and innovations that spread through the world like wildfire... It's not a cliche to say that we live in remarkable times.

"Immortal God! What a world I see dawning! Why cannot I grow young again?" -- Erasmus

"O my soul, do not aspire to immortal life, but exhaust the limits of the possible" -- Pindar

Happy new year!

Merry Christmas!

Sorry I haven't been blogging as much these days... But you can see why! A lot of end-of-year projects, and our new little girl. Here she is in her first holiday dress, meeting Santa for the first time... And looking a bit confused about the whole thing!

I'll blog next week... promise!

Open World 2011: WebCenter Presentations

I gave two presentations at Oracle Open World this month... one on Integrating WebCenter Content: Five Tips to Try, and Five Traps to Avoid! I broke it down into the big sections: contribution, consumption, metadata, security, and integrations. Special thanks to IOUG for sponsoring this talk!

My second talk was a case study based on a big project that completed recently, integrating WebLogic Portal, UCM, E-Business Suite, Autonomy IDOL, and a whole bunch of other stuff to make a global e-commerce web site. The client is in a highly regulated industry, and I was unable to get permission to use their name... but if you're curious about the details ping me!


If I missed you at Open World, I hope to see you at IOUG Collaborate 2012!

Running WebCenter Portal Pre-Built VM on Mac OSX

The WebCenter Portal team has put together a VirtualBox virtual machine to showcase the WebCenter Portal product. You can download it from Oracle. It's a big one: clocking in at 30 GB, so pack a lunch before downloading it.

The install instructions are pretty good for Windows and Linux clients... but if you're on a Mac (like me), it's missing one important tip. The file REAVDD-HOL-WC.ovf contains the information needed to import the files into a VirtualBox VM... but if you're running the free version of VirtualBox, it chokes on the import every time. The culprit is this line:

<SharedFolders> <SharedFolder name="Host" hostPath="D:\TEMP\Host" writable="false" autoMount="true"/> </SharedFolders>

If you're on Windows, and have a D drive, this works fine... but if you're on a Mac (and probably Linux), this will break the import. The fix? Use this XML instead:

<SharedFolders/>

And re-do the import... you'll need to re-set-up sharing once it's running. But at least now it will have a valid path!

NOTE: This is just meant to be a sandbox for testing integrations, and the like. It's not meant to be placed into a production environment... but, like all demo code, I'm sure I'l find it floating around in production eventually... and have to make it work.

WebCenter Mobile: PhoneGap and ADF Together at Last!

I was always a bit little skeptical about the initial mobile offerings for UCM and WebCenter. They never impressed me, because I felt strongly that these apps were fundamentally flawed in their design...

Why? Because they focused on being Mobile Applications instead of Mobile Web. The first time I held an iPhone, I noticed that it was running a browser that supported HTML5. The first Android was the same. This was at a time where HTML5 support was rare on desktop browsers, and few developers knew how to use it. Nevertheless, I predicted years ago that it would be the future... HTML5 was so powerful, that Flash and native mobile apps were unnecessary for 95% of applications. Many clients asked my advice on mobile apps, and my answer was always the same: "Skip native apps, and focus on the mobile web!"

This week, Oracle announced their next generation of the ADF Mobile toolkit... and (as I predicted) they are going the same route! Native code is no longer the focus: previously, you would create an ADF component, and it would be compiled down into native iOS or Android controls. No more! The next version will compile to HTML5 and be rendered in the mobile browser!

How can this be? With a technology called PhoneGap. It allows you to create your application in nothing but HTML5, render it in a browser, and still access native functionality (camera, location, files) with JavaScript functions. It's basically a wrapper around the built-in HTML5 browser, plus a plug-in library, which together give you an extremely powerful development environment. The next generation of ADF Mobile will be an ADF wrapper around PhoneGap, plus a few extra goodies (that I'm not allowed to talk about yet!). They call these hybrid applications because they are mostly HTML5, with a tiny bit of native code mixed in.

Well, what about those candy-coated user interfaces? How do I get those? The same way as always: mobile JavaScript toolkits. There are several available that can make very attractive interfaces, that render in any smartphone:

If you prefer to roll-your-own UI, I'd recommend Zepto as a minimalist framework instead...

What's next for the web, then? I believe that mobile application development will be the biggest driver for the adoption of HTML5 browsers. Yes, probably only 10% of mobile phones are HTML5-enabled smart phones... but people cycle through cell phones every 2 years. Compared that to the enterprise, some of which stubbornly refuse to upgrade from IE6!

I'd bet 90% of Americans will have a HTML5 mobile phone, before 90% of them are off IE6! Sad, but true... but good news for mobile developers!

UPDATE: Dang it! Just as soon as I blog about this, Adobe goes and purchases PhoneGap! What does this mean for Oracle? Tough to say... it's probably a good thing, since most of PhoneGap is open source. The only piece that's not Open Source is their nifty build engine. But, since Oracle already owns their own build engines (jDeveloper and Eclipse plugin), this is not a stumbling block.

UPDATE 2: It appears that Adobe has done "The Right Thing" and is submitting PhoneGap to the Apache group, and re-branding it as Project Callback. This will hep cement it as "the standard" toolkit for mobile app development.

The Oracle Non-Database?

Well, that was unexpected... Oracle has always been the gold standard for relational databases, but they are now throwing their hat in the "BIG DATA" ring with their new appliance... this "BIG DATA" stuff is also sometimes called NoSQL.

What's NoSQL? It's a software designed to manage very large data sets as key-value pairs, instead of in a relational database. Think big-giant-hashtable. The need emerged because some HUGE data sets needed management and analysis, but were so unstructured that it was impractical to put them in a traditional relational database. Really huge personalized web sites needed to create their own NoSQL solution, just to scale: Facebook made Cassandra, LinkedIn made Voldemort, Amazon made Dyamo, Google made BigTable, etc.

At Open World, Oracle announced several products in this area... One that I found interesting is an appliance based on the Hadoop database, which is used for analysis of HUGE amounts of unstructured data. I covered Hadoop's algorithms three years ago, warning that once JOINS were practical, it could threaten Oracle's database hegemony... but it looks like their Hadoop offering is a good blended mix: Hadoop for initial unstructured analysis, then migrate to Oracle for fast reporting.

I was also impressed with Oracle's new NoSQL offering, which is mainly for the storage of a massive amount of high speed, "lightly transactional" data. Think personalization, browser history, etc. This new offering is based on Oracle's existing BerkleyDB libraries: at 20+ years old, they're probably the oldest NoSQL database still in common use. In fact, a lot of the "big data" players are just wrappers around an array of BerkleyDB nodes. What makes Oracle's offering superior, is that it's just as fast as other NoSQL databases, but you can optionally add support for SQLite query support, instead of plain get/set methods. Also, you can add support for ACID transactions. Naturally, the queries will be much slower than if the data was in a RDBMS, and transactions will slow down the system... but at least it's available.

Not sure what the effects of this will be... especially since a great deal of these offerings are OpenSource! But, I'd wager that it won't take long for Oracle Applications to start using them in interesting ways...

The obvious ones are user tracking, event history, and business analytics. Previously, people would only track a fraction of user or system events, because it would be totally impractical to capture or analyze it. Amazon decided to do exactly that, and surprised everyone when they proved how much of a competitive advantage they were able to glean... With NoSQL, you could store way more data than before... and with Hadoop you can analyze way more...

Well folks, it looks like NoSQL has finally hit the mainstream! Can't wait for the inevitable Exa-doop server...

PowerPoint Tips from South Park

PowerPoint is a necessary evil... everybody is expected to give presentations in it, but few people are good at it. They cram too much information into one slide, and pack them full of data that might better go in a report. Presentations work best when used to persuade, it's an awkward tool when you try to educate. There's a reason PowerPoint was banned by the Pentagon:

"PowerPoint is dangerous because it can create the illusion of understanding and the illusion of control" -- Brig. Gen. H. R. McMaster

But alas... we're still stuck with PowerPoint... so we should probably make the best of it!

One of the ways to make PowerPoint presentations more compelling is to tell a story... unfortunately, most people are pretty bad at telling stories as well. There's an entire industry created around corporate storytelling that trains people how to engage your audience with a full-fledged story... but there's an even simpler approach. The creators of South Park stumbled on a formula that they still use to assemble stories:

These same rules can apply to making a PowerPoint presentation flow like a story.

You initially assemble your main points -- which is usually the hard part. Then, when assembling your points to tell a story, try to transition between your points with the word "therefore," or the word "but." Like so:

  • Slide 1
  • therefore...
  • Slide 2
  • but...
  • Slide 3
  • therefore...
  • Slide 4
  • but...

Simple, no? You'll be surprised how much better your presentations will "flow" from one point to the next with this method.

Naturally, not all presentations can fit into this pattern... for example, "Top 10" presentations flow numerically from one point to another... so if people doze off they can pick up the next chunk at the start. Also, there may be times where the dreaded "and then" transition is needed, such as when a point needs to be communicated over several slides.

Nevertheless, if you try hard to use better transitions, your story will be more compelling, and PowerPoint will be one notch less evil.

WebCenter/UCM Performance Tuning, Black Box Style!

I love doing performance tuning... It's typically a mundane process of tiny tweaks and digging for gold in log files, but for some reason I find it a blast. I usually do it for every client, and sometimes I have projects dedicated exclusively to tuning.

One cropped up recently, where a client was having craaaaazy slow performance with an 11g custom component that Shall Remain Nameless. It worked fine with small data sets, but on a page with 1000 items, the load time was 12 minutes. Thus begins our adventure! But first, some wise words from the grandfather of performance optimization:

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" -- Donald Knuth

Yarp... The first thing to do is establish a benchmark. Run some kind of automated test to time performance, and then start your tweaking. Also, be sure to put it in a nice table, so you can visually see just how awful the starting point is!

It's kind of a dull process-of-elimination to disable components, restart, and run another benchmark... but you have to do that in order to narrow down the offending code. I initially thought the problem was in one component... I was wrong... So, as boring as it is, it must be done to eliminate red herrings.

Once I found the offending component, I turned on some low-level tracing parameters. You can do this from the System Audit Information administration page. I usually turn on Verbose tracing, as well as these sections: requestaudit, pagecreation. When I did a small manual test, what I got back shocked me a bit:

pagecreation/6	09.13 17:55:47.774	IdcServer-31333	page generation took 10766 ms; gets 58863 funcs 24362 incs 9256 eval 160
requestaudit/6	09.13 17:55:48.012	IdcServer-31333	FOO_SERVICE 14.5684232711792(secs)

Woah... even a simple page was taking 14 seconds, 10 of which was in rendering the IdocScript! I checked, and these pages were far too complex for words. On a page with a 1000-item list, the component that Shall Remain Nameless was spitting out 15 Megs of HTML! Danger! Danger!

The fix? I used some of my tips from my web site performance tuning presentation, of course. I made a new custom interface, and leveraged the YUI Library that's built-in to UCM... specifically the DataTable widget. By bye IdocScript, hello JavaScript! That slimmed down the page from 15,000 KB to a manageable 300 KB, and all but eliminated the page generation time.

Problem solved, right? Not so fast... even with that the site was still slow. Next I suspected something in the database: bad histogram, missing index, whatever. So I turned on another low-level flag: systemdatabase. Please note: enabling this will turn your log files into a frigging Russian novel, so don't leave it on for too long... I ran another test, and got something like this:

systemdatabase/6	09.14 15:13:36.548	IdcServer-18413	53 ms. SELECT FOO_QUERY [Executed. Returned row(s): true]
systemdatabase/6	09.14 15:13:58.803	IdcServer-18413	Closing active result set
systemdatabase/6	09.14 15:13:58.804	IdcServer-18413	Closing statement in closing internals

Well... I was wrong again! Can you see the issue here? The query only took 53 milliseconds to run, so the database is hunky dory! But, it takes a full 12 seconds for UCM to release the connection. That means, somewhere deep inside the component that Shall Remain Nameless, some Java code is taking 12 seconds to post-process the database results. In some scenarios, it took over 40 seconds just to post-process the results.

What the heck is it doing???????

Don't know, don't care! Instead of digging through the component's code and trying to optimize that 40 second delay, I did what any sane web developer should do when faced with a poor performing black box: make a data cache! After quite a bit of digging, I found the magic function that was so very important that it took 40 seconds to run. So instead of calling it directly, I wrapped it up in a secure data cache. That cut the 40,000 milliseconds down to 4. You sometimes see stale data on the page, but that's always the case with a web interface... so it's usually a good tradeoff.

So... after improving their performance by 5 orders of magnitude, I patted myself on the back, and flew home...

The final benchmark numbers looked amazing... and I think that's why I find performance tuning is so satisfying. It's so very lovely to see the difference between the initial and final performance... and it's even better if you need to use a logarithmic scale to see them! ;-)

Recent comments