Upgrading to WCI 10gR4 – The Final Frontier
Recently, I worked with a long-time WebCenter Interaction (WCI) customer that requested our assistance in upgrading their Extranet from WCI 10gR3, to WCI 10gR4. As you probably know, WCI has been “end-of-lifed” by Oracle, meaning that the 10gR4 version (aka v10.3.3.0.0) is the last and final version. For many of us that have used WCI since it was a Plumtree product (including this customer), it is the end of an era.
But I digress…
The 10gR4 upgrade should have been a quick, simple, and painless upgrade. According to the Release Notes, there really wasn’t too much that changed from 10gR3 – or so we thought. As we progressed through upgrading their TEST environment, we encountered a variety of things that had changed, weren’t documented, and caused problems that we had to resolve before upgrading their PROD environment.
New Parameter on Method Call
This customer had written a few customizations and extensions to the out-of-the-box WCI portal. These should have all continued to work with 10gR4, but when we were testing, we were seeing an error from their code, stating that a method (com.plumtree.portalpages.browsing.login.LoginModel.GetSubPortalRedirectAfterLogin) could not be found. My first thought was that the method had been removed – perhaps it was an ‘internal-use-only’ method that Oracle decided was no longer needed or something. We looked in the API documentation, and the method was still there. Hmm. Weird.
After a bit of head-scratching, we realized that while the method was still there, what was causing the error was that its signature had changed! With 10gR3 and prior versions, the method had no parameters. But, in 10gR4, there now was a required parameter (IPTSession) that must be passed to the method. This was causing their code to fail, since they weren’t passing this parameter. Adding the now-required parameter to the method call resolved this issue.
[ Side note: This customer uses the .NET version of WCI, but you may have noticed that the links I’m using are to the Javadocs, not the .NET docs. This is because the .NET docs don’t even have this class or package documented – they are just missing (along with quite a few others)! We’ve noticed that the .NET version of the API documentation is very incomplete for some reason. So, even if you are a .NET API user, it pays to take a look at the Java version of the API documentation, as it appears to be much more complete. The two APIs (.NET and Java) are essentially the same – the .NET version of WCI is actually translated from the Java version – so you can safely use the Java docs even if you are a .NET customer. We’ve filed bug 18436590 with Oracle on this issue. ]
The Release Notes for 10gR4 makes absolutely no mention of any API changes! I checked with Oracle Support, and they were unable to find any documentation on this, or any other, API changes from 10gR3 to 10gR4. I haven’t done an extensive comparison between the API method signatures in 10gR3 and 10gR4, so there may be others that could trip you up. So, keep this in mind if you get the “method not found” error – it may not be because the method isn’t there, but that the parameters have changed.
New Advanced Search Adaptive Page Layout
Something that is documented (OK, mentioned) in the Release Notes, is that the Advanced Search page is now an adaptive page layout. This is great news, as it means you can customize it to meet your look-and-feel needs as you can with other pages. In this customer’s case, the new adaptive page layout for the advanced search results screen required some customizations to make it ‘fit’ (both physically and aesthetically) in their page.
<pt:kdpage.documentsdata> .url Property Returns JavaScript
The <pt:kdpage.documentsdata> tag is used on the knowledgedirectorylayout.html adaptive page layout. It returns a collection of documents (cards) from the Knowledge Directory that should be displayed on this page (taking into account the selected folder, pagination, etc.). For each document in the collection, there are a set of properties returned – name, id, URL, etc. Our customer had customized the out-of-the-box knowledgedirectorylayout.html file to change the look to match the rest of their site, and once we upgraded to 10gR4, the links to display a document stopped working. When someone clicked a link, the URL it took them to appeared to have JavaScript in it. What was going on?
We looked at the line in the custom knowledgedirectorylayout.html file (which was copied from the original Oracle-supplied .html file), and it was the following:
<pt:core.html pt:tag="a" href="$doc.url" title="$htmlEncodedName"><pt:logic.value pt:value="$doc.name"/></pt:core.html>
The above <pt:core.html> tag will output a normal <a> tag, with an href of the document’s url (from the $doc.url property). This looked fine (and hadn’t changed), so what was going on?
After quite a bit of digging, we figured out that the $doc.url property had changed in 10gR4! (And – surprise – no mention of this in the Release Notes either!) When we looked at the (new) out-of-the-box knowledgedirectorylayout.html file, that line had changed (and there was a new comment) as follows:
<!-- Bug-9380820: Adding the onclick attribute. That is having the url according to UserPrefrence. Document should open in the same window or new window. changing href attribute value from $doc.url to #. --> <pt:core.html pt:tag="a" href="#" onclick="$doc.url" title="$htmlEncodedName"><pt:logic.value pt:value="$doc.name"/></pt:core.html>
Comparing the two, and reading the comment, it appears that there was a bug (#9380820) where clicking on a document in the KD list should either open the document in the current window, or in a new window, depending on a user preference. The bug in 10gR3 was that the document always opened in the current window (which, if you look at the <a href=”xxx”> tag that was being created, makes sense). So, the ‘fix’ was to change the doc.url property to return a block of JavaScript that when executed, would either open the document in the same window or a new window, depending on the user’s preference setting. And, in the updated <pt:core.html> tag, you can see that the return value from $doc.url is now being used in the “onclick” attribute of the <a> tag, and the href attribute is just “#”.
While this ‘fixed’ the bug (which isn’t visible in MetaLink, BTW), it broke any other use of the doc.url property, including our customers’. An easy option would have been to mimic what Oracle had done to the OOB knowledgedirectorylayout.html, and move the use of the doc.url from the HREF attribute to the ONCLICK attribute of the <a> tag. However, that caused other issues. Our customer uses a FireFox add-in that allows them to download all of the links on a page at once, which they would use to download a whole folder at a time from the KD. By changing the HREF attribute to “#” and opening the document with JavaScript (like Oracle had done), the tool would no longer work (since the links didn’t have an actual URL).
So, what we ended up doing was building the HREF attribute a slightly different way. We replaced the <pt:core.html> tag and instead used the <pt:standard.openerlink> to get the URL for each KD document as follows:
<pt:standard.openerlink pt:objectid="$doc.id" pt:classid="18" pt:mode="2" title="$htmlEncodedName"><pt:logic.value pt:value="$doc.name"/></pt:standard.openerlink>
The resulting <a> tag contained the document’s URL in the href attribute as it did in 10gR3, allowing their download tool to continue functioning.
[ My 2 cents is that Oracle ‘fixed’ this bug entirely wrong. They should have left the doc.url property alone, and let it continue to return an URL (as its name and the documentation implies). They should have introduced a NEW property (e.g. “doc.openscript”) that could then be used to open it with JavaScript and also honored the “open in new window” user profile property. This way it would not break any existing code. But, that is just my opinion… 🙂 ]
ItemAsXPDateTime
This is a really weird one, and took quite a while to track down and resolve. The customer has a custom user property that tracks the date the user last changed their password. This property is defined as a ‘date’ type. When a user logs in, they have a custom PEI that checks the PasswordChanged property to see how long it has been since the user changed their password, and if it has been a while, prompts them to change it.
They do this by executing a query to get the set of properties for the user, then they were using the following code to return the value for the “PasswordChanged” property as an XPDateTime object (where ‘i’ is the index into profileProperties of the PasswordChanged property):
XPDateTime dateTimePropertyValue = profileProperties.ItemAsXPDateTime(i, PT_PROPIDS.PT_PROPID_PROP_VALUE);
Once we upgrade to 10gR4, we starting seeing seemingly random failures on this line of code, with the following stack dump:
com.plumtree.openfoundation.util.XPClassCastException: Error in function PTQueryResult.ItemAsXPDateTime (rowNum == 23, propID == 67108864): Unable to cast object of type 'System.String' to type 'com.plumtree.openfoundation.util.XPDateTime'. at com.plumtree.openfoundation.util.XPException.GetInstance(String strErrorMsg, Exception e) at com.plumtree.server.impl.core.PTQueryResult.ItemAsXPDateTime(Int32 rowNum, Int32 propID) in e:\build\root\Release\portalserver\10.3.3.x\portalobjects\build\x86\src\dotnet\com\plumtree\server\impl\core\PTQueryResult.cs:line 350 at com.acme.portalpages.browsing.login.CustomControl.getDateTimeUserProperty(String propertyName, Int32 userID, IPTSession ptSession)
Now, all user properties are actually stored in the database as String values, so what appeared to be happening is something was preventing the (Oracle) code from converting the String value in the DB into an XPDateTime value. Since the code worked for some users and not for others, we thought there must be an invalid character or something in the data for the users that failed, so we started to look in the DB (in the PTPROPERTYDATA table) to compare ones that worked with ones that didn’t to see what was different. What we found was surprising – there were NO differences! We even took values that worked and copied them from one user to a user that failed, and that didn’t fix it! We tried editing the PasswordChanged value via the Admin Portal UI, and that didn’t work either.
Ultimately, we never were able to determine why the portal was unable to convert certain users’ PasswordChanged value to an XPDateTime. (We did create an Oracle Service Request on this, too.) So, in the interest of time, we ended up coding up a workaround ourselves that basically returned the value for the PasswordChanged property as a generic Object. Then, we tested the ‘type’ of this object to see if it was a String, and if so, we converted it to an XPDateTime value ourselves. So, for some users, the portal actually returns an XPDateTime object for this property, and for other users, it returns a String, which we then convert.
So, not a true ‘fix’ in that we never have figured out why the portal is working this way, but it let the customer move forward with their upgrade, which to them was more important.
Other Anomalies
Finally, there were a few other anomalies that we encountered in the process that I feel worth mentioning.
- The installer for the WCI 10gR3 wouldn’t run on a set of boxes that we needed to install the AD Identity Web Service on. It would fail with the error “Windows cannot access the specified device, path, or file. You may not have the appropriate permissions to access the item.” We verified that the user we were logged in as had Administrator rights to the box, that the installer was located on a drive that we had permissions to, that the TEMP folder had space (and we had permissions), that the anti-virus package wasn’t blocking the install – all sorts of things. We never were able to determine why the installer wouldn’t work, unfortunately (although we suspect it was a Windows Policy of some sort causing the issue). We ended up installing the AD IWS on another box that didn’t have the problem.
- When we installed the Analytics Jobs (only) on a server, when we tried to run any of the jobs, we would get the following error:
Exception in thread "Main Thread" com.plumtree.analytics.core.exception.BeanNotFoundException: Cannot find bean with name 'runJobs' at com.plumtree.analytics.core.SpringUtil.getBean(SpringUtil.java:74) at com.plumtree.analytics.job.RunJobs.main(RunJobs.java:204)
After a lot of digging (and decompiling Oracle code), we discovered that the hibernate3.jar was missing. We were not able to reproduce this problem, but the best theory that we and Oracle were able to come up with was that you should copy the zip files for hibernate and cewolf to a local drive before installing Analytics. Apparently the installer has some known issues with installations from a network drive. We did this on subsequent installations, and did not experience the problem again.
Whew! So much for a ‘painless’ upgrade, huh? 😛
Overall, the upgrade went fairly well (preceding issues aside). Many of the issues we encountered could have been avoided had Oracle actually documented changes that they made to (public) APIs, instead of letting customers ‘trip upon’ the changes randomly. While we were able to resolve (or workaround) all of the changes, it has raised the question of “What else was changed that we weren’t told about?” and that we may not ‘trip upon’ for days, weeks, or months? I realize that as 10gR4 is the last release of WCI, there perhaps isn’t a lot of concern for the product, so some shortcuts were probably taken to just get it out the door.
I for one, will continue to mourn the loss of what was a great product, and look (hope?) to see Oracle incorporate some of WCI’s best qualities into the WebCenter Portal replacement.
RIP, WCI…
For more information about how TekStream can help you with Enterprise Portal upgrades, please visit our other Enterprise Portal Blogs, contact us at info@tekstream.com, or request to speak with an Oracle WebCenter Expert by filling out the form below.