A blog containing development tips I have learned through the years as a PeopleSoft developer.

Friday, July 22, 2016

Dynamic Java in PeopleCode

The PeopleCode language has a lot of features and functions. But sometimes, it seems there are tasks we need to accomplish that are just out of reach of the PeopleCode language. It is at these times that I reach for Java. I have written a lot about Java, so I'm sure many of you already know how to mix Java with PeopleCode. While certainly a rational solution, one of the pain points of a Java solution is managing custom Java on the app and process scheduler servers. Each time you update your compiled class (or jar) files, you have to restart the server. That might be OK in a stable production environment, where you don't intend to change code often, but in development, it is a real pain! Likewise, maintaining custom Java class and jar files through upgrades can be a little sketchy. Specifically, if you redeploy PeopleTools or rewrite psconfig, then it is possible you may miss some of your custom Java code. PeopleBooks tells us how to setup psconfig for custom Java classes, but again, that is just one more thing to manage through upgrades. Now, imagine being able to update your custom Java code with a Data Mover script. Further, imagine being able to run custom Java without making any changes to your application server. Imagine what it would be like to run Java without having to beg (or bribe) your admin for a "no customization" exception. It is possible today. The answer: Use JavaScript to interface between PeopleCode and the delivered Java Runtime Environment. Through the embedded Mozilla Rhino JavaScript script engine of Java, we have full, dynamic access to the JRE. When and how would you use this? Let's review some examples.

Custom HTTP Connections

For various reasons, some customers choose not to implement Integration Broker. These customers find themselves requiring integration, but without IB's networking features. An alternative to %IntBroker.ConnectorRequestURL is to use Java's HttpURLConnection.I strongly discourage this approach, but the question arises. The JRE is there, well integrated with PeopleCode, and ready for use. From PeopleCode, it is possible to create a Java URLConnection using CreateJavaObject("java.net.URL", "http...").openConnection(). A problem arises when we try to invoke methods of a HttpURLConnection, the real return value of URL.openConnection. Unfortunately, PeopleCode doesn't see it that way, which leads down the reflection path (we don't want to go there). This is where JavaScript can help us. JavaScript doesn't mind that URL.openConnection returned an HttpURLConnection even though it said it would just return a URLConnection. Here is an example:

Excel Spreadsheets

PeopleTools 8.55+ has a PeopleCode API for Excel, which means this solution is now irrelevant. I'm listing it because not everyone is up to PeopleTools 8.55 (yet). If you use this idea to build a solution for 8.54 and later upgrade, Oracle recommends that you switch to the PeopleCode Excel API. The solution will still work with 8.55+, but just isn't recommended post 8.54.

This solution uses the Apache POI library that is distributed with PeopleTools 8.54+ to read and write binary Microsoft Excel files. As with the networking solution above, it is possible to use POI directly from PeopleCode, but a little difficult because POI uses method overloading in a manner that PeopleCode can't resolve. Furthermore, POI uses methods that return superclasses and interfaces that PeopleCode can't cast to subclasses, leading to awful reflection code. Here is an example that reads a spreadsheet row by row, inserting each row into a staging table for later processing.

15 comments:

Jim, have you experimented at all with passing variables back and forth at different steps of a PeopleSoft -> Java -> JavaScript interaction (e.g., dynamic data being written to spreadsheet). I know there's a bind method that lets you do something like this.

It is my experience that this works really well with primitive data types (string, number, etc), and not so well with objects. That is why my examples include how to create PeopleCode objects from definitions. That way I can pass in a primitive string name for a definition and then create an instance of it in JavaScript.

The Java interface will retrieve any object and it will be an Object on the PeopleCode side. The problem is that it becomes an Object, which means any method invocation requires reflection. The whole point of this is to avoid reflection. With that in mind, I usually write JavaScript helper methods that will return primitives for each of the object properties, etc. Basically, I'm creating a helper/wrapper routine, which is what I would have done in Java anyway, so that I have something that is easier to work with from PeopleCode.

Hi Jim...Great work explaining this concept. I was able to run with this idea on tools 8.49 and 1.5 JVM and the Rhino standalone JAR. Binding properties to the javascript context works a little differently so I wanted to post my code in case someone else is trying to implement a similar solution.

/* get json from jobvite. Note that I'm not setting the content type of the header but that doesnt seem to be an issue returning the jason*/ /* also this is connecting NOT through SSL - ssl connection may take some extra work if its needed */ &JSONfromJobvite = %IntBroker.ConnectorRequestUrl(&jobviteURL);

Jim,We are on PT 8.55, we are working with portal objects. When we look at the navigation collections and the folders, each folder is having folder attributes, and the most common name is PTPP_IS_PWDEFN with attribute value Y. I am trying to understand what these folder attributes really mean and how do we identify which one to use when trying to use the Nav collection as landing page.

We just recently upgraded to PT 8.54 and are having some issues with the Apache POI libraries that are used for psquery. We have a very large client with over 350K employees and our HR users need to run queries with all employees in the result. When running to excel we are running into GC overhead limit reach errors and have to restart our PSQRYSRV processes to reset the heap. Any thoughts on how best to tune appserver memory for these new libraries with larger results?

I have struggling with this for sometime.Any help is greatly appreciated.

I'm trying to do a HttpPatch using the HttpClient jar file.Its giving me the more than one overload matches error in the execute method.As you can see I have commented the codes to try reflection with no luck.Can you help where I'm going wrong.

I am very happy to send this post, i have one quick question. my requirement was user's while click on one hiperlink/pushbutton one excel sheet should be downloaded based online line data. so how to write the code and if incase if i create Java script how to pass my bind values.

Please let me know if you have any idea about that it's very helpful for me.

@Ram the easiest way today is to use the PeopleCode API for Excel. If that isn't an option, then you can pass bind values or other parameters to the ScriptEngineManager as variables. You can see an example in this blog post: https://jjmpsj.blogspot.com/2015/09/javascript-on-app-server-scripting.html.

The views expressed on this blog are my own and definitely reflect the views of JSMPros, my employer. The views and opinions expressed by visitors to this blog, however, are theirs and do not necessarily reflect my opinions or the opinions of JSMPros.

Please be advised: this site contains code snippets and examples that may require modifications to delivered PeopleSoft objects. Before modifying delivered code, make sure your development team approves of your modification. Likewise, ensure that you have properly documented your modification according to your organization's best practices. You and your organization will be responsible for maintaining your modifications through patches and upgrades.

The author provides development tips and modification ideas for informational purposes only. Tips and techniques presented on this site should be considered proof of concepts only. Neither the author or his employer assume any liability for problems resulting from the implementation of these ideas.