Category: PeopleCode

PeopleSoft Generated URLs Go To the Wrong Instance

Story time. I built a process that would load people. If there was an error loading a person, it would send an email. Because I would have no way of knowing what might have been written to the log (SSN, birthday, etc.), I decided to just include a link to the screen where a user could review and fix the error. Everything worked great.

The problem was that in certain environments, that URL went to production. It should have gone to the test environment where we were validating the new development.

What was the fix? Here are my notes…

Read More

Pinging and Posting from PeopleCode

I had a need to Ping a server to see if the server could get to it.  I also tried to post to it.  This code could be helpful for others, so I want to share it.  A post should normally go through the Integration Broker, but I first developed it at a time when I had a product that was supposed to go on servers with diverse versions of Integration Broker.

The Ping code doesn’t seem very reliable for some reason.  Something on the Java side doesn’t always work.  Still it might be helpful.

   Local JavaObject &url;
   Local JavaObject &conn;
   Local JavaObject &r;
   Local any &line;
   Local string &output;
   Local JavaObject &inet;
   Local string &address;

   MessageBox(0, "", 0, 0, "hostname: " | GetJavaClass("java.net.InetAddress").getLocalHost().getHostName());

   &address = "localhost";
   &inet = GetJavaClass("java.net.InetAddress").getByName(&address);
   MessageBox(0, "", 0, 0, &address | "(" | &inet.getHostAddress() | ") reachable: " | &inet.isReachable(5000));
   &address = "www.google.com";
   &inet = GetJavaClass("java.net.InetAddress").getByName(&address);
   MessageBox(0, "", 0, 0, &address | "(" | &inet.getHostAddress() | ") reachable: " | &inet.isReachable(5000));

   &url = CreateJavaObject("java.net.URL", "http://www.google.com");
   &conn = &url.openConnection();
   &conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
   &conn.setRequestProperty("accept", "text/xml/html");
   &conn.setRequestProperty("accept-charset", "utf-8, iso_8859-1");
   &conn.setRequestProperty("userid", "????");
   &conn.setRequestProperty("pwd", "?????");
   &conn.setDoOutput( True);

   &output = "";
   &r = CreateJavaObject("java.io.BufferedReader", CreateJavaObject("java.io.InputStreamReader", &conn.getInputStream()));
   &line = &r.readLine();
   While &line <> Null
      &output = &output | Char(10) | Char(13) | &output;
      &line = &r.readLine();
   End-While;
   &r.close();

   MessageBox(0, "", 0, 0, &output);

Please make sure to adjust the URLs and hostnames to what you need.

Resources

New PeopleCode Dump Method

One of my old tricks was to create a PeopleCode dump from the system.  Then I could use a text editor tool such as gVim or Ultraedit to search through the code to find examples or certain uses of definitions.

Basically, a PeopleCode dump is easily created by searching for (Edit > Find In) a semicolon.  Because every statement must have a semicolon, it matches every statement of code in the system.  On the Find In dialog, checking the Save to File option will write out each line to a text file.

The problem is that Application Designer seems to load every line into memory.  If you don’t have a client machine with a ton of memory, you end up looking like this:

App Designer Out of Memory Error

 

Instead, I found this new tool called Decode PeopleCode.  You can download the latest zipped version of the program from here.

Once extracted, I had to configured the URL property in the DecodePC.properties file.  I set it to something like this:

url=jdbc:oracle:thin:@<server name>:1521/<db name>

I also had a problem with the JDBC driver for some reason.  It didn’t find the odbc5.jar file that was delivered.  I already had a copy of the odbc6.jar, so I just adjusted the classpath to include that.  If you run into the same problem, adjust the DecodePCODE.sh or DecodePCODE.bat file to contain the full path to the jar file.

Also, adjust the “outdir” property in the DecodePC.properties file to point to the directory where you want the output dumped.  Note that it will create a bunch of folders and files in that directory, so you may want to point it to an empty directory.

Then, I ran the program with this command to capture everything:

sh DecodePCODE.sh since 1901/01/01

Now, that creates each PeopleCode program in its own file.  The problem is that I want it all in a single file that I can run regular expressions against.  I could use grep, but I am used to a single file.  I cobbled this script together to build that single file:

#!/bin/bash


processFile() {
   outdirlen=$((${#OUTDIR} + 1))
   filename=$1
   lastUpdateFile=$( echo "$filename" | sed 's/\.pcode$/.last_update/' )
   peoplecodePath=${filename:$outdirlen}
   peoplecodePath=$( echo "$peoplecodePath" | sed 's/\//: /' | sed 's/\.pcode$//' | sed 's/\//./g')
   echo -e "\e[0K\r Writing: $peoplecodePath"
   echo "[$peoplecodePath]" >> "$OUTFILE"
   echo '/*   Details:' >> "$OUTFILE"
   echo '   Last Update User: ' $(head -n 1 "$lastUpdateFile") >> "$OUTFILE"
   echo '   Last Update Date/Time: ' $(tail -n 1 "$lastUpdateFile") >> "$OUTFILE"
   echo '*/' >> "$OUTFILE"
   cat "$filename" >> "$OUTFILE"
}


#  ------------------------------
#    Main
#  ------------------------------

OUTDIR=$( grep "outdir=" DecodePC.properties | sed 's/^outdir=//' | sed 's/\r//')
DUMPDATE=$(stat -c %y $(ls -rt | tail -n 1) | cut -d ' ' -f1 )
DATABASE=$( grep "^url=" DecodePC.properties | sed 's/^url=.*\///' | sed 's/\r//')
OUTFILE="$OUTDIR/all.pcode"
echo "outdir -- $OUTDIR  dump date -- $DUMPDATE  database -- $DATABASE"

echo "PeopleCode Dump $DATABASE   $DUMPDATE" > "$OUTFILE"
find "$OUTDIR" -type f -name \*.pcode | while read file; do processFile "$file"; done

That seemed to get the trick done for me nicely.

This program has more features than just this. You should explore it. It can check the code into a sourcecode repository to track changes. Kudos to whoever wrote it!

Resources

 

Null Date in PeopleCode

Just the other day, I needed to set a Date to null or blank, and I couldn’t remember how to do it.  Here’s my notes so that I can remember next time.  Javier’s blog came to the rescue:

Javier’s PeopleSoft blog: Setting Date Variables to Null in PeopleCode

The short version is: use the Date(0) function:

     Local Date &hireDate;

     &hireDate = Date(0);

Here’s some more information to explore a little more in depth…

Read More

Scheduling a Process from PeopleCode

The process scheduler provides a good standard way to launch a process.  You simply add a subpage to your run control page, and the delivered “Run” button does all of the work for you.  But sometimes, you want to run the process other ways.  Sometimes, you might want to create a more customized feel on a end-user page and launch a process from a push button.  Or, you might want to launch an additional process from an App Engine program.

In this post, I would like to drop notes to make this easier the next time I need to do it.

Read More

PeopleCode: Unzipping

I come upon a requirement to unzip a file in a platform independent way.  Jim Marion got me most of the way, but his code didn’t write it to file.  Here’s my adjustment to make a function that wrote it to file:

Function unzip(&inputZipFile, &targetDir)
  Local JavaObject &zipFileInputStream = CreateJavaObject("java.io.FileInputStream", &inputZipFile);
  Local JavaObject &zipInputStream = CreateJavaObject("java.util.zip.ZipInputStream", &zipFileInputStream);
  Local JavaObject &zipEntry = &zipInputStream.getNextEntry();
  Local JavaObject &buf = CreateJavaArray("byte[]", 1024);
  Local number &byteCount;

  While &zipEntry <> Null

    If (&zipEntry.isDirectory()) Then
      REM ** do nothing;
    Else
      Local JavaObject &outFile = CreateJavaObject("java.io.File", &targetDir | &zipEntry.getName());
      &outFile.getParentFile().mkdirs();
      Local JavaObject &out = CreateJavaObject("java.io.FileOutputStream", &outFile);
      &byteCount = &zipInputStream.read(&buf);

      While &byteCount > 0
        &out.write(&buf, 0, &byteCount);
        &byteCount = &zipInputStream.read(&buf);
      End-While;

      &zipInputStream.closeEntry();
    End-If;

    &zipEntry = &zipInputStream.getNextEntry();
  End-While;

  &zipInputStream.close();
  &zipFileInputStream.close();
End-Function;

unzip("/tmp/myzipfile.zip", "/tmp/out");

Resources