×
Tips and Techniques

Application Engine Development Tips

By Larry Grey • May 13, 2006

Application Engine can be fairly handy in a PeopleSoft developer’s toolchest. Aside from all of the useful batch processing things that it can do, it can also be useful for providing ways of running PeopleCode against a system directly from within Application Designer. This can be used for things like testing some PeopleCode or providing some developer productivity utilities. David Bain and I used to do some presentations on developer productivity for PeopleSoft developers, and taking advantage of Application Engine was one of the tips that we used to always mention.

An example utility is the version control work that we’ve been doing for our products at Grey Sparling. When you have a project that needs to be checked into the source code control system, the project needs to be split up from one large file into a multitude of separate files (the exact number of objects that you have in your project). We have an App Engine program that does this for us, but we needed a way to specify the exact project name to the program. In regular App Engine programs running on a server, you’d have some page for entering run control parameters and the program would look at these. But when you run the App Engine program directly from within Application Designer, you don’t have those facilities available to you.

So what we end up doing is a couple of things. First, we take advantage of the COM integration in PeopleCode and use that to have Internet Explorer provide a prompt with the list of projects in the database.

When you have an Application Engine program open in Application Designer, you can press the traffic light icon or select Edit->Run Program from the menu. You’ll get a prompt like

this.

.ae_run_splitter

I always turn on the save to log checkbox, and then press Enter or click OK. Once the program starts, Internet Explorer pops up the list of projects in the database and lets you select one. The project name that you select is then used by the rest of the Application Engine program to do it’s work.

ie_prompt_for_project

Here’s what the code looks like:

SCROLL BOX

The IEPrompt function takes a title and a label and an array of choices and returns back the selected choice. We use a hidden form field as a flag for when the user has made their choice since we can’t actually catch COM events from within PeopleCode. The HTML that we generate from PeopleCode is not super fancy, but it gets the job done.

The other functions in the code are to assemble the list of projects from the database into a PeopleCode array and then to put the entire thing together.

How about if you wanted to supply the parameter yourself without getting prompted? Maybe you, as the developer, want to run this AE program as part of a bigger script. The answer is to just pass the parameter on the command line and use a little PeopleCode to parse out the values.

In order to do that, I ported over this C# based command line parser from The Code Project. It was easiest to port by utilizing Java from PeopleCode.

SCROLL BOX

The C# regular expression classes are fairly similar to what is available in Java. The only minor headache was that PeopleTools was having problems looking up one of the Java methods used (which we’ve seen before in previous blog entries), but that was fairly straightforward to get around. The workaround is to repeatedly compile one of the regular expressions instead of just once, but in this particular usage scenario, the overhead of that is so negligible that we don’t care.

As a side note : native regular expression support was added the 1.4 version Java Runtime Environment, so if you’re on an older version then you’d need to look at some extra libraries for adding regular expression support, or this code won’t work.

Labels:

Stay Updated

25 Replies to “Application Engine Development Tips”

  1. When you call a C function from PeopleCode, the shared library/DLL that implements the C function is being loaded directly into the PeopleSoft process running the PeopleCode.

    So, if your App Engine program is running as a scheduled process on the process scheduler machine, then it will get loaded there. If the App Engine is being called on the appserver, then the C function would be running on that appserver machine.

  2. Chris,
    If I am trying to call a C function from an App Engine PeopleCode, where does my C func need to reside? Is it on the application server or the process scheduler server?

    Is there a way to get this working if I place the c library on the Process Scheduler Server?

    Thanks
    Subash

  3. Hi All,

    I was trying to generate trace to have a look at why the function cannot be called although the external library is placed in the bin folder in $PS_HOME.

    In Appserver logs, I found that although I have mentioned the function name as “QABatchWV_Startup”, it tries to look for funtion “QABatchWV_Startup_intf” and shows a message ” Unable to find external function ‘QABatchWV_Startup_intf’ in library ‘qabwvcd’ “.

    There was a point in PeopleBooks which said, “The PeopleCode declaration and function call syntax is the same regardless of platform, but UNIX libraries must be compiled with an interface function”. Has this got anything to do with this error?

    Any inputs on this will be useful.

    Thanks
    Shibu Keloth

  4. Chris,

    Thanks for pointing the typo.

    But unfortunately I get the same error inspite of correcting the name of the library. One point to note is that I have my library files on the machine on which application server is installed and I am trying to call the library using an application engine which runs on a process scheduler installed on a different machine. Should my library files be placed on the machine on which process scheduler is installed.

    I am a bit confused about where the application engine looks for to find the library path?

  5. Chris,

    Thanks for the quick reply.

    The library is provided by an external provider for some functionality which we want to use from PeopleSoft.

    In PeopleBooks it is given “To support processes running on an application server, you can declare and call functions compiled in dynamic link libraries on windows (*.DLL files) and shared libraries on UNIX (lib*.so files.) The PeopleCode declaration and function call syntax is the same regardless of platform, but UNIX libraries must be compiled with an interface function.”

    I am not sure what it means by “.. UNIX libraries must be compiled with an interface function”. Is there anything else we need to do apart from calling the library (to compile the library)?

    The code I am using is as follows:

    Declare Function QABatchWV_Startup Library “libqabwvcda.so”
    (integer Value As number) Returns integer As number;

  6. Hi Shibu, we’re glad you like the blog content.

    From the error message that you’re getting it sounds like the library is being found, but that the function name is not being located. Could be a problem with name mangling.

    Is the library one that you are compiling yourself? or is something general?

  7. Hi Guys,
    Your Blogs have been very useful.
    I am facing a problem in trying to call a C function from PeopleCode within an Application engine program. The function is located in a library in LINUX (.so file). To invoke the function I need to set the path for the application to understand where the library sits. I have set the path in CLASSPATH, PS_LIBPATH and LD_LIBRARY_PATH in psconfig.sh file in both the application server and the process scheduler.

    Still I get the message “External function ‘function_name’ not available. Can you suggest whether my steps are correct or is there any other place to set the library path.

    Thanks
    Shibu K

  8. Keep in mind the original point of this blog post, which was some ways of using App Engine from within Application Designer.

    Page activate PeopleCode always runs on the application server. Technically, you can call COM objects from PeopleCode running on the application server *if* the app server is running on Windows.

    But I doubt that you’d want to load up Internet Explorer on the application server each time that someone opens that page in their web browser. Not so good for performance 🙂

  9. I tried using the CreateObject(“InternetExplorer.Application”) on the Page activate and it was giving an error “Class InternetExplorer.Application is not found. Should it be used only in a App Engine? Pl. advice.

  10. Chris, 2 years later, and this post is still generating interesting comments… great work! I was just reviewing this code and noticed your use of GetCommandLineA. Brilliant! Most of us PeopleCode programmers are stuck in the run control record paradigm. You have demonstrated that it is possible to pass arguments to an AppEngine from the command line, just like any other application.

  11. There are a few likely reasons why a function wouldn’t work from a dll that you have created.

    One possible reason is that you’re not actually exporting the function from your .DLL. I would definitely double-check your .DLL’s function exports to be sure your function is there.

    Another likely reason is that you have the wrong calling convention for your function. PeopleTools expects that external functions are using standard calling convention (I think that PeopleBooks mentions this), so if you’re not using that, then it won’t work (although I think that PeopleBooks also mentions that you can declare alternate calling conventions though; can’t remember for sure at the moment)

    The other possibility is that you are exporting a function out of something that is being compiled as C++ code so your function name is being mangled. Check your function exports to be sure that the name is what you’re expecting.

    The last tip is to try calling your .DLL function from some other environment (like VB). That can help determine whether the problem is with the .DLL or with the way that you are invoking it from PeopleTools.

  12. I am also having the same error. i just created the dll and put that dll in PS HomeBinServerWinX86 folder. I also enter this path in PATH environment variable still having the below error

    External function ” not available.

    The specified external function was not found in the DLL as defined in the PeopleCode program.

    Make sure the DLL is in the Windows PATH. Verify that the routine is properly linked. Review the program for errors

  13. Hi I am trying toi create a DLL to use in peoplesoft. now I have cretaed DLL through Visual studio. I have placed that DLL in C:windowssystem32 of machine in which the PS is installed . I was not able to register it. Still I am facing this error “External function Str6Test not available. This external function was not found in the dll as defined in peoplecode program.

    Make sure dll is in the Windows PATH. Verify that the routine is properly linked…”

    Did I miss some stem in this . Plz help me out

  14. You can launch IE with a URL and get some level of control over it from PeopleCode, but not as much as you might like.

    Mainly because there’s no way to catch IE events from within PeopleCode, so the only way to know what the user is doing is to do polling inside PeopleCode.

  15. Is there a way in PeopleCode to do something very similar to this, but with a URL instead?

  16. That message is a little bit misleading.

    The C function interface that PeopleCode supports works on Unix/Linux as well as Windows, but the naming is different.

    Instead of .dll files, you have .so files (so stands for shared object).

    The other difference is that on Unix/Linux the .so files are prefixed with “lib”. So if you had str6.dll on Windows, you would have libstr6.so on Linux.

  17. Hello All, I have a problem I need to call an external function, I did this:

    Declare Function Str6Test Library “str6” (string, string, string, string, string, string) Returns integer;

    But Peoplesoft returns this Error:

    “External function Str6Test not available. This external function was not found in the dll as defined in peoplecode program.

    Make sure dll is in the Windows PATH. Verify that the routine is properly linked…”

    My machine is Linux and I don’t know how to do this call for Linux.

    Sorry about my english.

    Thanks and Regards

  18. Is there a way that i could open an excel or notepad in the client machine(from the peoplesoft frontend) through peoplecode?

  19. OK, this time I took the pieced apart snippets and actually saved them as standalone program in App Designer instead of trusting myself before uploading 🙂

  20. Thanks Chris. I hope you’ll have time for a future blog entry on dll functions. Since PIA, I tend to no longer pay much attention to COM integration and external functions on the server, because of portability issues. This application engine example, however, is perfectly valid and innovative too. The technique presented in this post should definitely be part of a developer’s toolchest.

    I’d also like to point out another omission: in your command line parsing code snippet, the definition of ParseWindowsCommandLine is not included. My guess is that this is where GetCommandLineA and lstrcpyA are called.

  21. Good catch. I thought that I was being helpful by splitting the code into two separate parts for the posting, but I didn’t actually paste the split code back into App Designer to make sure that it was still valid. I’ve uploaded an updated version now.

    The return value is a good catch as well. Definitely not nit-picking though. When you get the parameter passing between PeopleCode and .DLLs wrong, then Bad Things can happen.

    I used to do a lot more of that years ago for an internal SFA system that we had built in PeopleTools for some international groups in PeopleSoft (using the Windows progress bar for file copies, FTP-ing files, etc.). Since declaring these functions in VB is fairly close to PeopleCode, I used to reference a lot of VB sample code.

    For most things that was pretty straightforward, but dealing with structs and nulls was pretty challenging. The secret is to allocate the memory yourself and do some low level poking that way. I don’t know how much need there is for that these days, but maybe it’s worth a future blog entry.

    Of course, even Microsoft gets the translation of the actual API calls into VB code wrong 🙂

    http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239588

    They obviously pinched the same example VB declaration for Sleep() that I did!

    Here’s the actual function declaration from MSDN

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/sleep.asp

  22. For a while there, I almost thought there is an undocumented PeopleCode function named Sleep().

    I think you’ve omitted the external function declaration of Sleep on kernel32 library. Also (sorry for nitpicking), this function does not need to return a value, can be used by PeopleCode without &tmp if declared as:

    Declare Function Sleep Library “kernel32” (long Value As number);

Comments are closed.

Request a Demo