Using Java Reflection in PeopleCode - Part 3

This is part 3 of our post, where we are attempting to invoke a correct Java Method from PeopleCode by using Reflection techniques. If  you are jumping to this post right from the internet, I would suggest you to refer the following links first.

Part 2 - Initial explanation of the solution, getting started to read the Metadata of Class file from PeopleCode.

To get the correct method to pass to invoke, we need to identify the method based on the argument types. For our example, the right "square" method is the one that has an input type of "Double". [ java.lang.Double]. To get the right method of type java.lang.reflect.Method we have to use the "getDeclaredMethod" of the object &Obj_getcoreclass_l that we got scope for in Part 2.  Now, the method "getDeclaredMethod" needs the following inputs to return the right method back for us

1) Method Name => We have it with us. The method name for us is "square".
2) Parameter types => This is of type java.lang.class[], and it is basically an array of input types that the method "square" accepts. This parameter types is vital as it eventually helps in returning the right method back to us for invoking.

So, the key for us is to decode "Parameter types" first. To do, that we declare a standalone java object for "Double" type as shown below;

Local JavaObject &Obj_doubletype_l = GetJavaClass("java.lang.Double").TYPE;

After this step is done, we create a java object of type java.lang.class[], and pass this "Double" object type as a parameter to that; This is done by the following PeopleCode statement;

Local JavaObject &Obj_argtypes_l = CreateJavaObject("java.lang.Class[]", &Obj_doubletype_l);

This object &Obj_argtypes_l, will now serve as an input of "Parameter types" for the method "getDeclaredMethod". So, the following code

Local JavaObject &Obj_getcorrectmethod_l = &Obj_getcoreclass_l.getDeclaredMethod("square", &Obj_argtypes_l);

invokes the "getDeclaredMethod" , by passing "square" as method name and "Double" as the input parameter. What we get back out of it is an object of type java.lang.reflect.Method  by probing the "image" class's "square" method(s). At this point, if you want to know if the right method has reached to the scope of PeopleCode, you can use the following methods in java.lang.reflect.Method  to do so..

Error &Obj_getcorrectmethod_l.toString(); => This returns " public static double image.square(double)".

…Great, we have got the right method for us to invoke now.

Finally, to invoke the right method "square" , we have to use the "invoke" method of java.lang.reflect.Method. This "invoke" method requires the following inputs;

1) obj -> The objectname where the method resides => In our case, the object is available under " &Obj_getcoreclass_l".
2) args -> This is of type java.lang.Object [] . They serve as the input data for the method "square".

We wil focus on (2) again. To construct the inputs, we will use the PeopleCode as shown below

Local JavaObject &Obj_consargarray_l = CreateJavaObject("java.lang.Object[]", CreateJavaObject("java.lang.Double", "2.5"));

Essentially, we create an object array and push the java.lang.Double into it and pass the input value of "2.5" into this. Finally, we invoke the right method by using the following peoplecode statement;

Local JavaObject &Obj_finalinvoke_l = &Obj_getcorrectmethod_l.invoke(&Obj_getcoreclass_l, &Obj_consargarray_l);

This "invoke" method executes the right "square" method and the following statement;

Error &Obj_finalinvoke_l.toString();

gives an output of 6.25..the right one we were after..

If you look at the steps, they are quite tedious and we have to use this roundabout approach as PeopleSoft cannot do it automatically for us. You can always get around this by writing a wrapper class and invoke that wrapper from PeopleCode, which could alleviate this great deal of complexity.

Have you every tried using Reflection techniques in PeopleCode? Struck with a problem? Post it for us and we will have a look..

2 comments:

  1. HttpURLConnection urlconnection = (HttpURLConnection) url.openConnection();
    urlconnection.setRequestMethod("POST");
    urlconnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
    urlconnection.setDoOutput(true);

    Above code i achieved in reflection, but now OutputStreamWriter out = new OutputStreamWriter(urlconnection.getOutputStream());

    not able to achieve as im not able to pass proper type parameteres to OutputStreamWriter constructer as i have used refelection.

    ReplyDelete
  2. I am getting overload on FIleinputstream.. I am trying to pass file object and there are 3 methods available. How do i get past this>

    ReplyDelete