Skip to content


WSDL to Component Interface Faults

Component Interfaces is one of the coolest features in PeopleSoft from a technology point of view. The folks in Pleasanton either had great deal of prescience (or were extremely lucky) when they designed the Component framework to so easily be encapsulated and accessible using a variety of interfaces. By its very nature MVC implies this kind of design property but so far I have yet to see something similar in any of the other software packages I have dealt with. Perhaps the fact that the metadata is wholly stored in the database and that view components cannot have any logic outside of PeopleCode enforces a clean break between the view and the controller. This compared to other technologies where the view is too tightly bound to the model and/or logic to make such a partition costly and – in some instances – impossible.

Anyways, boring stuff to anyone but myself.

Given how much CI is touted in the marketing materials, you’d be surprised at the dearth of information available. PeopleSoft provides a rather poorly documented SDK_BUS_EXP (oh geez, thanks) and there are a few How-Tos in the Oracle Support Knowledge Base. Documentation for implementing CI over Web Services is especially impoverished considering that most of the Oracle (nee PeopleSoft) documentation stops after creating the the web service itself, failing to show any examples of how to actually implement the service consumption side.

Currently I have been using C# .NET 3.5 / Visual Studio 2008 to consume a PeopleSoft CI-based web service. After having created a Service Reference I was greeted with a bizarre assortment of “types” and absolutely no documentation for what to do next. After much toil I was able to throw together a small console application that allowed me to perform all of the operations exposed by the CI including Create, Find, Get and Update. However, to my dismay I was unable to get any meaningful error conditions back from my calls to the CI.

Specifically, any errors would throw and exception with a simple message: “Component Interface API”. Debugging seemed fruitless as none of the variables contained any error messages or indication of what actually went wrong.

The point of this entry is to say simply that the following code will show you the error messages (specifically the SOAPException) from a failed CI call (excuse the lack of indenting):

catch (System.ServiceModel.FaultException e)
{
System.ServiceModel.Channels.MessageFault messageFault = e.CreateMessageFault();

if (messageFault.HasDetail)
{
XmlElement faultDetails = messageFault.GetDetail<XmlElement>();
foreach (XmlNode node in faultDetails.ChildNodes)
{
Console.WriteLine(node.Name + “: ” + node.InnerXml);
}
}
Console.WriteLine(“Exception: ” + e.Message);
}

Hope this helps someone. The tip jar is looking awfully broke these days…

Posted in Uncategorized.


Drive me crazy…

Just in case this helps anyone out there –

It spent the last hour trying to figure out how to test if a variable is null or empty in Application Class PeopleCode on PeopleTools 8.47.

All()? Doesn’t work. None()? Nada. Those functions work on RECORD.FIELD structures only. Go figure. Maybe they fixed this in newer versions of Tools but no dice for 8.47. And forget PeopleBooks. No help there.

I had to dig through delivered Application Classes hoping to see how PeopleSoft themselves implemented these functions.

Want to test a string? Use (&var = “”) or (&var <> “”). Great! But guess what, this doesn’t work for date types.

To test whether a date variable is null, you have to do the following:

Local Date &mynulldate;

Then test (&mydate = &mynulldate). Yes, you have to create a new date variable (which points to a null date value) and then test against that. Amazing… Alternatively you can cast the Date or DateTime as string and then test to see if the string is empty.

In other words:

/* To test strings use: */

if &myvar = “” then /* do whatever… */ end-if;

if &myvar <> “” then /* do whatever… */ end-if;

/* To test dates use: */

Local Date &nulldate;

if &mydate = &nulldate then /* do whatever… */ end-if;

if String(&mydate) = “” then /* do whatever… */ end-if;

Posted in Uncategorized.


PeopleSoft VMware Support

I am a huge fan of VMware and have been using it since some version long ago before the company was acquired by EMC. I use it as an integral part of my day-to-day activities and actively promote its use within our company and clients.

VMware (and virtualization in general) is the Matrix for hardware. Once your server has been virtualized it has no idea that it isn’t a physical server; in fact unless you know where to look (MAC address, device drivers, system tray icon if you have it setup thusly, etc.) you’d be hard pressed to say if the server you were connected to was virtualized or not.

The driving rationale behind the wave of virtualization has been the ability to recapture under-utilized CPU and centrally manage thousands of servers at a comparatively low cost. The Achilles Heel of virtualized servers is hard disk I/O but even that is becoming a moot issue with the uptake of SSD devices. My T500 laptop running 64-bit Windows 7 and VMware Workstation 7.0 on a OCZ Vertex 60GB SSD with 4GB of RAM can boot a Windows 2008 server instance in under 15 seconds and have PeopleSoft running in less than 30 seconds altogether. How much more so then if you have an array of SSDs (notwithstanding the reliability and cost concerns, both of which are rapidly becoming less of an issue).

So, back to the topic at hand. Does Oracle support PeopleSoft on a VMware platform?

The short answer is yes.

The long answer is that Oracle initially denounced VMware / virtualization. Then they decided to offer their own virtualization solution OracleVM and so supported a virtualized PeopleSoft only on OracleVM. Then they realized that their stance to support only their own virtualization technology in the face of growing customer demand for VMware doesn’t really hold water except when considering their desire for global domination and so finally relented (without really admitting anything).

The most recent statement on the topic is found in Oracle Support Document ID 847092.1 which states:

Oracle certifies our products (PeopleTools and EnterpriseOne Tools) on certain operating systems (including Solaris, HPUX, Linux, MSWindows, AIX etc.), not on specific hardware configurations. Therefore, as long as a customer configures their machines with supported operating systems, we will treat them as though they are independent systems and provide full support.

So in a roundabout way Oracle has embraced the brave new virtualized world with open arms without actually endorsing or having to certify any particular underlying technology. In other words, if your operating system is supported on your virtualization platform and Oracle has certified your operating system for PeopleSoft then you’re in the clear.

VMware opens up a whole new toolbox for your organization to effectively deploy and maintain PeopleSoft servers. The significant operational and sunk costs associated with high availability an fault-tolerance are now significantly reduced, allowing even smaller, budget conscious organizations to consider enterprise-level uptime.

Sorry Neo, I’m taking the blue pill.

Posted in Infrastructure.


Considerations when calling Java from PeopleCode

When developing custom or extended functionality in PeopleSoft it is useful to consider invoking Java objects to supplement functionality available in PeopleCode.

PeopleSoft applications are able to invoke static and non-static objects (with some limitations) natively through PeopleCode. There are some nuances and subtleties that require work arounds or wrapper classes — for instance, it is not easy to cast objects when using Java through PeopleCode — but for the most part Java works well with PeopleCode.

There are however certain architectural limitations that require careful design up front when developing more complex Java-integrated solutions.

Standard Java application deployments employ levels of object persistence that have scope for duration of the application itself. An easy example of this is a connection pooling object that is started when the Java application server is started and is accessible until the application server is shutdown. In other words, objects/variables of this nature are said to have application scope.

In general, one could describe the types of variable scope available in PeopleSoft according to the following (in increasing life-span):

  • Function/Local – Local variables are available only within the function and are inaccessible outside of the function. In PeopleCode we declare these as Local.
  • Class – Class variables are available within any function within a class and may or may not be accessible outside the class (nuances of this are not relevant to this discussion). Usage of these in PeopleSoft are implicit in the context of Application Classes and there is no explicit Class declaration.
  • Component – Component variables are declared as Component and are available so long as a user remains within a component. Once the user leaves the component the variable/object is destroyed.
  • Global – Variables declared as Global are available so long as a user session is active until a user logs out. Global variables are NOT shared between other users.

There is no level of variable scope beyond Global. In other words, there is no way to declare a variable that has a life time BEYOND a user’s session and/or that is accessible amongst multiple users.

The simple reason behind this is that PeopleSoft employs a stateless set of server processes to process user activity.

First, a quick primer on the PeopleSoft Application Server.

The PeopleSoft Application Server is actually a set of worker processes that perform different functions. These functions are stateless (meaning they don’t store any data). The reason for this is simple — an application designed around a stateless pool of processes is one way to approach highly-available, fault-tolerant design. If a user is working on one application server and that application server dies (or one of the worker processes dies), the user can easily be routed to another application server (or worker process) and things continue without a hitch.

These application server processes are managed through a central “daemon” call the BBL. Without going into detail, the BBL dictates when each application server process starts, restarts, shuts-down and garbage-collects (aka recycles). The server process that brokers the user interaction with a component — the Component Processor – is called the PSAPPSRV process.

So where does a user’s session lie? It is actually the web server that stores all the different user session variables. Every time a user visits a page the data in the user’s session is compared against the data in the database. Inconsistencies lead to the dreaded “Data inconsistent” error message. This is why a user can lose their connection to an application server but can NOT lose their connection to a web server.

Going back to our original discussion, whenever PeopleSoft encounters PeopleCode that calls a Java object, the application server instantiates a JVM process [note: if you are not familiar with "JVM" you need to go back and review the Java runtime model]. Simply, the PSAPPSRV that encounters the Java call will instantiate a JVM. The life of the JVM depends on the life of the PSAPPSRV process which, as we discussed earlier, is at the whim of the BBL.

Where does this leave us? For starters, Java objects have an unpredictable lifespan as the JVM can be destroyed on an ad hoc basis (as viewed from the JVM). In other words, as developers we cannot rely on a scope of a Java object beyond the current PeopleCode being executed. Java objects also cannot be shared amongst users as there is no way for one PSAPPSRV process to access the JVM of another PSAPPSRV process.

In other words, PeopleSoft lacks variables of application scope.

This has several consequences as many useful Java packages (I use the term loosely) rely on application-level persistence to function. Going back to the connection pooling example, if PeopleCode were to call a connection pooling object that object would be created and destroyed EVERYTIME the code was run, thereby negating the benefits of connection pooling. To illustrate:

  1. The Component Processor (PSAPPSRV) encounters PeopleCode which calls Java.
  2. PSAPPSRV instantiates a JVM.
  3. The JVM creates the connection pooling object.
  4. Code executes which uses the connection pool.
  5. The code completes and the connection pooling object is destroyed (and for all intents and purposes unavailable).
  6. The JVM is not necessarily terminated.

Compare this to a typical Java application server scenario:

  1. The Java application is started.
  2. The connection pooling object is instantiated.
  3. Repeated calls to the application make use of the single, shared connection pooling object.
  4. The Java application is shutdown sometime in the future (for maintenance, etc) and at that time the connection pooling object is destroyed.

Obviously the use case described here is quite specific but the limitations revealed herein need to be understood before designing any complex Java-based solution for PeopleSoft. One concrete example is trying to use PeopleSoft to call OpenOffice’s document conversion facility (an exercise which is left to the reader — I hated these in University…).

BTW — Anyone who wishes to deploy a turnkey PeopleSoft integrated document conversion solution (i.e. for converting eRecruit/Candidate Gateway resumes from one format to another) are invited to contact Attain Solutions as they offer such a product.

Posted in PeopleCode.


Custom Search Match Fields

Search/Match is an extremely powerful feature in PeopleSoft. Unfortunately, the delivered functionality is restricted to matching on only a few fields and PeopleSoft provides little to no information on how to extend functionality to additional fields. In fact, the “Setting Up Search/Match” PeopleBook is littered with the statement: Warning! Adding new search fields require significant programming effort and is not recommended.

For example, out of the box you can Search/Match on first name, last name, DOB, SSN and a few other fields. But what if you want to Search/Match on Driver’s License? Or provincial/state-wide Student ID?

I started out writing a full background and explanation of everything that I did but it became worthy of a movie script so the abridged version below will have to suffice. I’d be happy to provide more details should anyone actually need it.

The information below applies specifically to a case where a post-secondary institution client wanted to search/match on a provincial student ID for incoming transcripts and applications. One of the pre-requisites is that the external reference numbers are already associated with the PeopleSoft Employee IDs/Student IDs in the PS_EXTERNAL_SYSKEY and PS_EXTERNAL_SYSTEM tables.

Steps:

1. Create a new Search/Match Result Field definition on PS_EXTERNAL_SYSTEM.EXTERNAL_SYSTEM_ID

2. Add the Search Field to a Search/Match Rule

3. Customize the program to (1) fetch EXTERNAL_SYSTEM_ID and then pass it to the Search/Match logic. In the case of ADTRNPST we write a procedure to fetch EXTERNAL_SYSTEM_ID into $EXT_ID. Then we locate the series of calls to insertsearchchar() and add our own definition:

Do insertsearchchar($SearchDtTm, 'EXTERNAL_SYSTEM_ID', $EXT_ID, #Return_code, $Err_Msg)
 If #Return_code = 0

4. If appropriate, add functionality to INSERT new EXTERNAL_SYSTEM_IDs in the event that the Search/Match returns no result.

Voila! Search/Matching is now enabled on a non-delivered Search Field.

Posted in Student Admin.