Saturday, May 22, 2010

Accessing PeopleCode Rowsets from Java

A reader recently asked how to create instances of the Rowset class from Java. I believe the question was more about IDE and classpath setup than it was about actual Java code. But, since it can be difficult to figure out how to use PeopleCode objects in Java, I thought I would post an example:

package test.peoplecode;

import PeopleSoft.PeopleCode.Func;
import PeopleSoft.PeopleCode.Name;
import PeopleSoft.PeopleCode.Rowset;

public static String getOprDescr(String oprid) {
Name recName = new Name("RECORD", "PSOPRDEFN");
Name fieldName = new Name("FIELD", "OPRDEFNDESC");
Rowset r = Func.CreateRowset(recName, new Object[] { });

r.Fill(new Object[] { "WHERE OPRID = :1", oprid });

return (String)r.GetRow(1).GetRecord(recName).GetField(fieldName).getValue();
}
}

Notice that the first parameter to CreateRowset is a Name object and the second is an empty array. If I were creating a hierarchical Rowset (similar to a component buffer), then I would fill the array with additional Rowset objects, as described by the CreateRowset PeopleBooks entry. Another important difference between PeopleCode and Java is that the "RECORD" and "FIELD" parameters to the Name constructor must be upper case.

Here is some PeopleCode to test this example:

MessageBox(0, "", 0, 0, GetJavaClass("test.peoplecode.RowsetTest").getOprDescr(%OperatorId));

What about the IDE's Java project classpath? If your IDE supports library definitions (like JDeveloper), then add the JAR %PS_HOME%\class\peoplecode.jar as a new library and then add the library to your project.

31 comments:

Chili Joe said...

Great example Jim. I'm curious if there's a way to access the component buffer rowset from java (i.e., pass a reference to it).

Jim Marion said...

Hi Joe, thank you for the compliment. Yes, you can either pass the component's Level0 Rowset (my preferred method) to a Java method or your can call Func.GetLevel0().

ManoNag said...

Hello Jim,

Thanks for all the good articles in your blog.

I'm looking for Documentation for all the Application Packages and classes delivered with PeopleSoft Product. Something like Java Documentation.

Wouldn't be nice, that documentation also included in PeopleBooks.

I hope, I explanation is understandable. Waitin for your reply.I'm eagerly waiting for this type of documentation, so that, I can code lot more effectively.

-Mano

Jim Marion said...

@ManoNag, what you say is true. It would be nice. Actually, you can find PeopleBooks documentation for delivered supported reusable App Classes. For example, you will find lots of documentation about the MultiChannel Framework (MCF) and the pluggable encryption API.

What you won't find is documentation on app classes and API's that PeopleSoft developers created, but didn't intend for customers to reuse. As you say though, it makes you more effective to reuse delivered code, whether it was intended for reuse or not.

I've heard rumors from old timers in PS development about a documentation tool, but I've never seen it. I don't work directly in PeopleTools development, so I don't see everything. I am more of an internal PeopleTools customer.

In the absence of documentation, you have to dig deeply into the delivered code to figure out what it does.

One thing to keep in mind is that documented API's are considered stable. Undocumented ones are subject to change. What this means is that code you write that uses an undocumented API may break when you apply a patch or bundle. This can happen with documented API's too, but is less likely.

ManoNag said...

Thank you Jim, for a very quick response.

Without any documentation on delivered app packages and classes, how can anyone understand the logic.

In PeopleSoft Financials 8.4, if I want trace the logic and to make necessary changes, it used to be really understandable.B'coz, the code used to have all the known functions which are explained in the PeopleBooks.

But in PS FIN 8.8 and after, there is really heavy App Package usage, which sometimes really annoying to go through the complete code.

Anyways, I hope, sometime soon we may get a documentation for all these delivered Packages.

I'm not sure, I'm asking the right question or killing your time. If you have any information on this documentation, please post on your blog.

-Mano

Jim Marion said...

@ManoNag, I have the same documentation you have. If you want more, you will have to open a case with Oracle Support. Yes, there is an additional layer of complexity now.

Dan said...

<rant>I've long complained to anyone who would listen (and many who apparently didn't) about how poor PeopleSoft "in-code" commenting is. Occasionally one will see some well documented code, but it's the exception. Often there isn't even any indication of the purpose of the code. We require our developers to fully document any customizations and custom code. Why can't Oracle?

PeopleBooks have improved greatly over the years but not code comments.</rant>

Jim Marion said...

@Dan, my comment? ... No comment ;)

The PeopleCode/Java API has been especially difficult because the parameters are all "Object" which is basically any non native data type.

Unknown said...

Hi Jim,
Can you create a row set from an ApiObject or a String like this:

Local ApiObject &Job
&RS1 = CreateRowset(ApiObject.JOB);
&JOB_READ = &RS1.Fill();

Unknown said...

Hi Jim,

Can you CreateRowset from an ApiObject or a String?

Local ApiObject &Job
&RS = CreateRowset(ApiObject.JOB);
&JOB_READ = &RS.Fill();

Local String &Job
&RS = CreateRowset(String.JOB);

Jim Marion said...

@Iqan, From a string, yes. Just use:

Local String &Job = "JOB";
Local Rowset &RS = CreateRowset(@("Record." | &Job));

Asgar said...

Hi jim,
Thanks for all the articles from you, especially the undocumented ideas.
My question is, Can we call the user defined peoplecode function from java? How?

Say I have a peoplecode function in a default event of a record field, usually we declare it to call from peoplecode.

But how this can be done in java.

Jim Marion said...

@Asgar, you can call app classes from Java, but I haven't seen anything describing how to call a FUNCLIB. With that, I see two options:

1. Create a wrapper app class that calls the FUNCLIB function

2. Move the FUNCLIB code into an app class.

Here is the PeopleBooks documentation for calling App Classes from PeopleCode. I don't think it has changed much since tools 8.4 released.

Please note: Your Java needs to be running inside an app server session to call an app class.

ashok said...

Hi Jim,
I Am using hrms9.0.In that Permissions and role will give blank page.
How do i get permission and roles page options like options

kumar said...

I am using HRMS9.0.
Permission and roles Will not give any options.How do resolve my problem.

Jim Marion said...

@Ashok/@Kumar, I've never seen that before. I suggest you create an incident with Oracle Support

kumar said...

Hi Jim,
I placed a grid in the scroll level 1
and second grid i was placed in scroll level 1.
When i am saving page it gives error as No data for scroll is response.
How do i solve the Problem.
Thank you.

Jim Marion said...

@Kumar, it sounds like you didn't add any fields to the grid. If you did, then make sure the fields belong to an SQL view/table, not just derived/work fields.

kumar said...

I did as sql table only ,
Why it gives like that.

Johnm said...

Hi Jim,

I am new to PeopleSoft and I have a task to pull large amount of employee and company data from peoplesoft. I looked at this article and it seems to work for me. I was wondering are there any other way to get data from peoplesoft using Java? (Like web service or something else) I appreciate your help.

Thanks
John

Jim Marion said...

@Johnm, there are a million ways to get data out of PeopleSoft. Just remember, the example in this article only works when run from PeopleSoft (App Engine, Online PeopleCode, etc), and that is because it needs the Java Native Interface to access the PeopleCode objects.

Yes, you can use web services to get data. You can either take the tooling approach and publish a WSDL from PeopleSoft, and then consume from your external system, or take the light weight approach and just use REST or REST-like services (depends on your PeopleTools release). Search this blog for REST if you are interested.

If you have to move large amounts of data and this is a one-time move, then you may want to run against the database directly. This is the most efficient way to move large amounts of data. It really depends on whether you need business logic and whether or not you have security access.

Johnm said...

Jim,

Thank you very much. I am not allowed to use DB directly because of security. I am looking at Component Interface that can be exposed as Web Service and consumed by third party apps. What I am not sure is whether the CI peoplecode allows me to write adhoc query and return collection. Is this possible?

- John

Jim Marion said...

@John, CI based web services are great for changing data, but a bit heavy for data extraction. The query web services may be a better alternative. You can read about them in the Reporting Services PeopleBook. If you are using an older version of PeopleTools that does not support "Query as a Service" then you can create your own service operation and OnRequest handler that uses the PeopleCode Query API. You can read about the Query API here.

For extracting data, I think using query is a very good alternative (FYI, Query and CI's are different technologies and don't fit together directly. A developer might use them in the same project, for example iterate over query results, creating a CI instance for each query result, but the two are different).

I think this is a very good challenge for someone new to PeopleTools. If you choose a Web Service approach, then you will learn something about:

* Integration Broker
* PeopleCode
* App Classes and inheritance
* The PeopleCode Query API

Unknown said...

hi, Jim
I m facing problem to call peoplecode in java.. there is a problem for native library... can u tell me the Oracle Connector for database

M Asim said...

hi Jim
I am getting the error below when executing java code.
Exception in thread "main" java.lang.UnsatisfiedLinkError: PeopleSoft.PeopleCode.Func.CreateRowset(Ljava/lang/Object;[Ljava/lang/Object;)LPeopleSoft/PeopleCode/Rowset;
at PeopleSoft.PeopleCode.Func.CreateRowset(Native Method)
at Test.getOprDescr(Test.java:25)
at J_P.main(J_P.java:23)

Jim Marion said...

@M Asim, it sounds like an environment issue. I suggest you post your question to the OTN Forum

Jim Marion said...

@sarfaraz, when you ask for the Oracle Connector, are you choosing to just go direct to the database and skip the PeopleCode data access classes? If so, then what you want is JDBC and the Oracle JDBC driver jar file.

Unknown said...

hi JIm..
I want to update record from the PeopleSoft API that is generated from Components Interface.. Suggest me how i do update, insert data in record throug java ...
Thanx In Advance

Jim Marion said...

@sarfaraz, I suggest you start with the PeopleBooks entry on Java/Component Interfaces

Unknown said...

Hi Jim;
can u give little suggestion and hint for making a new peoplesoft Portal in which I can add database. in other words i want a new project and want a separate Portal for that..
i will very thankful to u

Regards Sarfaraz

Jim Marion said...

@sarfaraz, When you say you want a separate portal, do you mean a portal registry where menu items are stored or do you mean a separate database? In regards to separate portals, PeopleSoft delivers the EMPLOYEE, CUSTOMER, SUPPLIER, and PARTNER portals with no provision or licensing allowance for creating more. Technically speaking, however, creating a new site or workspace in the Interaction Hub (Enterprise Portal) will create a separate portal registry.