×
[searchandfilter taxonomies="search"]

Java and PeopleCode Tips and Tricks – Part 3

By Chris Heller • August 30, 2006

I haven’t written anything on the Java and PeopleCode series (part 1, part 2) recently, so I thought I’d whip something together this evening.

As previously discussed in the series, there are a few, um, quirks in the bindings between Java and PeopleCode. One typical workaround when you can’t cross between Java and PeopleCode successfully is to write some additional glue code on the Java side to provide an easier “target” to work with. This post will discuss a few tips and techniques for doing it all from the PeopleCode side.

Why would you want to avoid writing the Java glue code to simplify things? Well, it’s certainly not to avoid the complexity of Java (as the rest of this post will show). A more common reason is to avoid needing to distribute the compiled Java code out to each application server (which can be the source of various logistical difficulties).

On with the code. The use case here is to take an image and modify it so that we can stamp some text on it. The example comes from an article that shows how to use the Java Advanced Imaging libraries that are part of the standard Java environment as of Java 1.4.

The actual working code is below. Let’s start by looking at the first line of code that causes problems.

&jBufImage = &jImageIO.read(CreateJavaObject("java.io.File", &sSourceFileName));

This line of code will trigger the infamous “more than 1 overload matches” PeopleCode error. If you look at the relevant Javadoc, you’ll see that there are indeed multiple versions of the read method. Java can tell these apart by the type of the parameters being sent in, but PeopleCode only uses the number of parameters to differentiate among methods in a Java class with the same name.

In order to call this method from PeopleCode, we’ll need to use reflection. Reflection is how Java lets you determine class metadata (such as what methods it has and what parameters they take) at runtime.

Here’s what it looks like in action. This is broken into separate lines for clarity, but as you’ll see in the code, you can combine these where it makes sense.

&jReadArgTypes = CreateJavaObject("java.lang.Class[]", &jIOFileClass);
&jReadMethod = &jImageIOClass.getDeclaredMethod("read", &jReadArgTypes);
&jReadArgs = CreateJavaObject("java.lang.Object[]", CreateJavaObject("java.io.File", &sSourceFileName));
&jBufImage = &jReadMethod.invoke(&jImageIO, &jReadArgs);

This is easier to explain working from the bottom up. In order to call a method via reflection, we need to have the correct Method classinstance and use it’s invoke method. That’s what the 4th line is doing. The first parameter, &jImageIO, is the same object that we were trying to use before, and the second parameter is an array of parameters that invoke() will pass along to the “real” method.

Getting that parameter array is what line 3 does. When we have all of the values that are ever going to be in the array, then using CreateJavaObject with the braces, [], at the end of the class name is nicer than using the CreateJavaArray PeopleCode function. Mainly because we can pass all of the values in at once instead of setting them one by one as CreateJavaArray forces you to do.

We also needed to have the actual Method object. That’s what line 2 is doing. We call the getDeclaredMethod() method of the underlying Class object (this is the actual Java class that defines what a Java class is; chicken, meet egg) and pass it the name of the method that we want, along with array of the parameter types (not the parameter values!) that the method expects.

You can get the underlying Class object for any Java object by calling the getClass() method (there are examples in the code below). But when you have a JavaObject in PeopleCode that you obtained via GetJavaClass (instead of CreateJavaObject), then you actually have a PeopleCode reference to the class and not an instance of java.lang.Class. The PeopleCode reference allows you to call static methods on the class, but if you call getClass() on it, you’ll get an error. The secret to getting to a java.lang.Class instance for a particular class when you don’t have any instances of that class is to do something like this.

&jImageIOClass = GetJavaClass("java.lang.Class").forName("javax.imageio.ImageIO");

Now &jImageIOClass is an actual java.lang.Class instance, suitable for the reflection work that we’re doing.

Finishing things off, in line 1, we created the array of parameter types that we needed for the call to getDeclaredMethod(). The parameter types are specified by using their underlying java class, so you definitely want to be sure that you understand the difference between a java class and the java.lang.Class object which describes that java class.

Whew! That’s a lot of explaining to do just because PeopleCode doesn’t resolve all Java methods properly. What’s worse is that we’re not done yet. We now have another problem.

In the original line of PeopleCode, we called a method (“read”) that returns a Java object. Specifically an object of type java.awt.image.Bufferedimage. But we can’t use it as a BufferedImage object, because PeopleTools looks at the return type for invoke() and sees that it returns java.lang.Object, which is the base class for everything in Java. If you try to do something useful with &jBufImage (like get the dimensions of the image), PeopleTools will give you a “method not found” error.

Thankfully the underlying JVM still understands that this is a BufferedImage object and not just a java.lang.Object. So we can (read “have to”) use reflection again in order to use our BufferedImage. Of course, since we’re using reflection with BufferedImage, that means that any Java objects that we get back from reflected method calls are also misunderstood by PeopleTools (it will think that they are instances of java.lang.Object rather than whatever they really are).

So, once you fall into needing to use reflection within PeopleCode, you end up using a lot of it.
Believe it or not, it’s not so bad once you wrap your head around it. It took me longer to write this post than it took to write the code below since the extra work is essentially just some extra typing.

Obviously if you are doing a lot of Java/PeopleCode integration, then you’d be better off just writing a little bit of glue code on the Java side to avoid all of this, but when you’re just doing something quick (like using Java hashmaps instead of faking it with 2 dimensional arrays in PeopleCode), then this technique works well.

Finally, here is the actual code, along with the starting image (found in your PeopleTools directory) and the altered image.

Scroll box

Labels: PeopleCode, User

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Hiding the PeopleSoft Pagebar in all component

By Chris Heller • August 25, 2006

We had an interesting “Ask the Experts” question yesterday about how to disable the PeopleSoft page bar across the entire system. The page bar is what has the “New Window”, “Customize Page”, and “Copy URL to clipboard” links in it.

d6

There is a personalization setting for the “Customize Page” link that can be defaulted completely off at the system level, but the other options can only be turned off by going into each component and changing these properties. Financials 8.9 has 6723 components in it. Not something that you want to do one at time, especially since changing these settings is technically a customization.

One potential workaround to this is to just use SQL and update the component properties manually, but you generally don’t want to muck around with making direct updates to the PeopleTools tables (and you’re still customizing a ton of objects – you’re just doing it faster).

The other potential workaround that can be used still involves a customization, but a less invasive one. It involves using a little CSS to hide the page bar. This one line of JavaScript will do the trick.

document.write("<style>#PAGEBAR { display: none; }</style>");

If you put this into one of the delivered JavaScript programs that is added to every page (which is a customization), then you’ll be set.

Note that you haven’t actually disabled this functionality, just hidden it. So if you’re really desperate to keep people from using the pagebar, then you will have to disable it on each component so that the backend knows that it’s disabled as well.

Labels: , ,

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Application Designer Index Management tip

By Chris Heller • August 23, 2006

David Kurtz has a good tip on his weblog about how to get rid of an annoying little bug in the index management in Application Designer. David knows what annoys DBAs about PeopleSoft – he wrote the book on it(literally).

The underlying source of the problem has to do with the fact that some of the internal PeopleTools code still thinks that it is supporting some platforms that are actually not supported (Allbase!).

The problem of code cruft in PeopleTools is actually something that I’ve had in my list of blog topics to write about for awhile, but it’ll have to stay in the queue a bit longer. For now, check out David’s post for how to make Application Designer behave 🙂

Labels: ,

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Associating database connections with PeopleSoft users

By Chris Heller • August 13, 2006

A common headache for DBAs managing PeopleSoft applications is not knowing which user a particular piece of SQL is being executed for. This happen because the SQL is being executed by the application server under a privileged user account and not the PeopleSoft user (who probably doesn’t even have a database login).

The DBA can go ahead and kill the connection at the database, but they can’t explain to the user what happened. Of course, the end user just sees it as a PeopleSoft error (PeopleSoft does not handle killed connections very gracefully) and they try it again. Which just annoys the DBA even further. A vicious circle indeed.

At the Mid-Atlantic RUG last week, this topic came up in a few different discussions. Some of the DBAs there weren’t familiar with the EnableDBMonitoring option for PeopleSoft application server domains.

When this is turned on (and it’s on by default in PeopleTools 8.43 and up), then each time the application server begins doing work on behalf of a different user than it was previously doing work for, it will set a variable in the database session with information on that user.

Platform Support.

  • Oracle. You can see the information in the CLIENT_INFO field of the V$SESSION Oracle system view.
  • SQL Server. The information is available in the context_info field of the sysprocesses system view in the master database. This is a varbinary field, so you’ll need to cast it as varchar to view the data. There is also a PeopleSoft version of the sp_who stored procedure (called sp_pswho) that will return this information. Unfortunately this stored procedure does not get installed automatically when you install PeopleSoft. You’ll need to do it manually. A script to install this can be found in appendix B of the SQL Server for PeopleSoft Performance Tuning Red Paper.
  • DB2/zOS. The DISPLAY THREAD command will display the PeopleSoft user ID in addition to it’s regular information. Other DB2 platforms (Windows, Unix, Linux) do not support this command.
  • Sybase. Later versions of Sybase support this feature, but I’m not sure about how to access the information in the database. I would assume that an additional column was added to the sysprocesses view (similar to SQL Server), but I don’t have access to a Sybase installation to verify that at the moment.
  • Informix. Informix does not support this feature.

Labels: Database, Performance

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Grey Sparling Experts coming to a city near you!!!

By Chris Heller • July 27, 2006

Well, at least a city near you if you live near Richmond, VA or Washington DC.

We’ve been asked to present at the Mid Atlantic Regional Users Group in Richmond, VA on Friday, August 11. As part of that trip, we’ve been setting up meetings in the Washington DC area on August 9, and in Richmond on August 10. We still have a few open slots, so if you’d like to meet personally with one of the experts, contact us (we are giving out freebies to customers we meet with that will help with developer productivity).

Look for upcoming announcements for other conferences and user groups in the coming weeks.

Labels: 2006

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Fixing Report Manager

By Chris Heller • May 22, 2006

For those who know about Report Manager, it’s the PeopleSoft-delivered means of finding and accessing reports. For those who support people who use Report Manager, there are quite a few significant usability issues with it.

Issues? What issues?
The main issue with Report Manager is that it doesn’t know very much about the reports that it manages, which means that it’s limited from the start. It also has limited features to allow configuration of the behavior of this product. Because it’s the primary means by which users access reports, these limitations have significant ramifications with the user satisfaction, adoption and productivity in reporting.

Unfortunately, most BI tools aren’t a whole lot better in terms of managing and accessing reports.

So, how do you fix it?
Grey Sparling fixed it by doing three main things:

  1. We capture the information that describes the content of a report.
  2. We allow you to use that information in combination with information in your PeopleSoft application to provide a rich user interface for organizing, finding, and describing the reports.
  3. We allow you to configure the behavior of organizing, accessing, and using reports.

The end-result is a product named Report Explorer, which is revolutionary in how it solves these problems.

What do you mean, revolutionary???

The reason its revolutionary is that it is the only product that uses artifacts in your business application to help describe and organize reports in business terms. It’s also revolutionary in the amount of control you have over the behavior of the user interface.

So, how do I learn more?

I’m glad you asked. We’ve recorded a demo that shows the product in action here. We’ve also put out a marketing brief that describes it here. Finally, if you want to talk with us about it in person, our contact information can be found here.

Labels: ,

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Little known Row Level Security hook

By Chris Heller • May 18, 2006

In my previous posting on passing parameters to nVision, I briefly mentioned something that was unknown to one of the other experts here at Grey Sparling (and if he didn’t know about it, then probably not many other people do as well). Therefore, it warrants its own posting.

Although you can use the query security record to perform data security, you can also accomplish this by adding OPRID, OPRCLASS, or ROWSECCLASS as a key field (but not list box field) in the record definition.

Here’s an example of how it works (both with and without security applied).

With Security
In a financials database, there is a view called SP_PROJ_OPRVIEW, which is intended to allow security at the project level for individual users. The delivered record definition has the following settings for the OPRID field:

f2

Now, if you were to use this record in PS/Query, you would get the following SQL:

SELECT
FROM PS_SP_PROJ_OPRVW A
WHERE A.OPRID = 'VP1'

Without Security

Here’s the same record, with the OPRID key set as a list box item (which turns off row level security for it)

f2

The SQL coming from query would then be as follows:


SELECT FROM PS_SP_PROJ_OPRVW A

Labels:

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Application Engine Development Tips

By Chris Heller • 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.

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.

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: PeopleSoft

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Deeper dive explanation of Siebel Analytics by Mark Rittman

By Chris Heller • May 8, 2006

In my previous blog entry on nVision and Siebel Analytics, I shamelessly embedded a couple of screenshots from Mark’s Blog.

This morning, he posted an in-depth explanation of the platform and how it works. For those who want a look into the crystal ball showing the foundation of application reporting in Fusion applications, this posting is a must-read.

Labels: Fusion

Put the Appsian Security Platform to the Test

Schedule Your Demonstration and see how the Appsian Security Platform can be tailored to your organization’s unique objectives

Request a Demo

Start your free demo

"Learn how you can reduce risk with rapid threat protection, audit response and access control. All from a single, comprehensive platform"

Trusted by hundreds of leading brands