Discussion:
How to work with an external java method that returns a Java long (primitive type)
(too old to reply)
Franzw
2019-02-05 08:00:01 UTC
Permalink
I am writing some TDI ISIM code and I have come upon a problem that I have difficulties solving in (pure) TDI.
Consider this ISIM API method : https://www.stephen-swann.co.uk/javadoc/sim6.0/com/ibm/itim/apps/Request.html#getID%28%29
It returns a Java long primitive type - not an object - and what I seem to trick TDI (or really the underlying Javascript engine) it returns a java.lang.Double which is basically removing the lower significant bits...

I am wondering what I can do to solve this - and I am looking into 2 ways :

1.Using Java reflection - but I do not see a way of converting the long into a object this way

2.Writing a Java (jar file) wrapper - I believe this would be similar to what the complexTypeFC functionality - but I would like to avoid custom jars in my solution.

Does anybody have an idea to solve this ?

IF - and that is a big if - I have to go with solution 2 I would like to combine the 2 options - i.e. have a generic Javascript function that take the class, method and return object type as input and then uses the reflection API to actually execute the method and some generic Java code to perform the transformation from the primitive to an object. The reason for this is of course to make it reusable for all TDI'ers :-)

All ideas are welcome :-)

Regards
Franz Wolfhagen
Franzw
2019-02-05 08:29:26 UTC
Permalink
Post by Franzw
I am writing some TDI ISIM code and I have come upon a problem that I have difficulties solving in (pure) TDI.
Consider this ISIM API method : https://www.stephen-swann.co.uk/javadoc/sim6.0/com/ibm/itim/apps/Request.html#getID%28%29
It returns a Java long primitive type - not an object - and what I seem to trick TDI (or really the underlying Javascript engine) it returns a java.lang.Double which is basically removing the lower significant bits...
1.Using Java reflection - but I do not see a way of converting the long into a object this way
2.Writing a Java (jar file) wrapper - I believe this would be similar to what the complexTypeFC functionality - but I would like to avoid custom jars in my solution.
Does anybody have an idea to solve this ?
IF - and that is a big if - I have to go with solution 2 I would like to combine the 2 options - i.e. have a generic Javascript function that take the class, method and return object type as input and then uses the reflection API to actually execute the method and some generic Java code to perform the transformation from the primitive to an object. The reason for this is of course to make it reusable for all TDI'ers :-)
All ideas are welcome :-)
Regards
Franz Wolfhagen
It looks like https://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/MethodUtils.html could do the job - and that is available in TDI (or ISIM/WAS) - but it is available in my environment :-)

If anybody has the necessary knowledge to show me how to call the Request.getID() via the MethodsUtils to get it to return a java.lang.String or java.lang.Long I would be very grateful.

I know I will be able to figure it out my self using a lot of trial and error - but if I can do shortcut with some help it would be nice...

regards
Franz Wolfhagen
Franzw
2019-02-05 09:56:20 UTC
Permalink
Post by Franzw
Post by Franzw
I am writing some TDI ISIM code and I have come upon a problem that I have difficulties solving in (pure) TDI.
Consider this ISIM API method : https://www.stephen-swann.co.uk/javadoc/sim6.0/com/ibm/itim/apps/Request.html#getID%28%29
It returns a Java long primitive type - not an object - and what I seem to trick TDI (or really the underlying Javascript engine) it returns a java.lang.Double which is basically removing the lower significant bits...
1.Using Java reflection - but I do not see a way of converting the long into a object this way
2.Writing a Java (jar file) wrapper - I believe this would be similar to what the complexTypeFC functionality - but I would like to avoid custom jars in my solution.
Does anybody have an idea to solve this ?
IF - and that is a big if - I have to go with solution 2 I would like to combine the 2 options - i.e. have a generic Javascript function that take the class, method and return object type as input and then uses the reflection API to actually execute the method and some generic Java code to perform the transformation from the primitive to an object. The reason for this is of course to make it reusable for all TDI'ers :-)
All ideas are welcome :-)
Regards
Franz Wolfhagen
It looks like https://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/MethodUtils.html could do the job - and that is available in TDI (or ISIM/WAS) - but it is available in my environment :-)
If anybody has the necessary knowledge to show me how to call the Request.getID() via the MethodsUtils to get it to return a java.lang.String or java.lang.Long I would be very grateful.
I know I will be able to figure it out my self using a lot of trial and error - but if I can do shortcut with some help it would be nice...
regards
Franz Wolfhagen
Solved !!! - much easier than expected...


This piece of code show how (code is success hook - request is in the connector property) :

myLoader = com.ibm.di.loader.IDILoader.getInstance();
try {
task.logmsg(myLoader.getPathForClass("org.apache.commons.beanutils.MethodUtils"));
} catch(err) {
task.logmsg("Error occurred: " + err);
}


importPackage(Packages.org.apache.commons.beanutils);

myRequest = thisConnector.connector.getProperty("requestId");
task.logmsg(myRequest.getID().getClass().getName());

myMethodUtils = new MethodUtils();
myRequestID = myMethodUtils.invokeMethod(myRequest,"getID",null );
task.logmsg(myRequestID.getClass().getName());
task.logmsg(myRequestID);

Returns this output on my system :

10:50:08,576 INFO - /C:/PROGRA~2/ibm/isim/lib/commons-beanutils.jar
10:50:08,591 INFO - java.lang.Double
10:50:08,591 INFO - java.lang.Long
10:50:08,591 INFO - 4400178258828090940

The request is validated and correct.

It shows that the MethodUtils is part of the ISIM setup which is no problem as the Request class is in the same lib directory - but if you want to do this outside an ISIM server you need to add the apache commons jar yourself...

HTH
Regards
Franz Wolfhagen
Sufyan Khan
2019-02-15 13:24:22 UTC
Permalink
Post by Franzw
I am writing some TDI ISIM code and I have come upon a problem that I have difficulties solving in (pure) TDI.
Consider this ISIM API method : https://www.stephen-swann.co.uk/javadoc/sim6.0/com/ibm/itim/apps/Request.html#getID%28%29
It returns a Java long primitive type - not an object - and what I seem to trick TDI (or really the underlying Javascript engine) it returns a java.lang.Double which is basically removing the lower significant bits...
1.Using Java reflection - but I do not see a way of converting the long into a object this way
2.Writing a Java (jar file) wrapper - I believe this would be similar to what the complexTypeFC functionality - but I would like to avoid custom jars in my solution.
Does anybody have an idea to solve this ?
IF - and that is a big if - I have to go with solution 2 I would like to combine the 2 options - i.e. have a generic Javascript function that take the class, method and return object type as input and then uses the reflection API to actually execute the method and some generic Java code to perform the transformation from the primitive to an object. The reason for this is of course to make it reusable for all TDI'ers :-)
All ideas are welcome :-)
Regards
Franz Wolfhagen
Hi Franz,

You can do this in a very easier way.
Stephen posted about the same in his blog (https://blog.stephen-swann.co.uk/2012/02/tivoli-directory-integrator-and-long.html?m=1).

This happened because the toString() conversion within Javascript when operated on a Long object is incapable of retaining precision.
So, what you can do is wrap the String.valueOf() method inside a Java class and then use it in TDI.


Java Code:

package itimutil;
import com.ibm.itim.apps.Request;
public class util{
public static String getRequestID(Request request){
if ( request != null )
return String.valueOf(request.getID())
else
return "";
}
}


Use the same method in TDI -

var TIMProcessID = Packages.itimutil.util.getRequestID(request);
task.logmsg("INFO", "TIMProcessID: " + TIMProcessID);



Regards,
Sufyan Khan
Franzw
2019-02-16 15:30:35 UTC
Permalink
Post by Sufyan Khan
Post by Franzw
I am writing some TDI ISIM code and I have come upon a problem that I have difficulties solving in (pure) TDI.
Consider this ISIM API method : https://www.stephen-swann.co.uk/javadoc/sim6.0/com/ibm/itim/apps/Request.html#getID%28%29
It returns a Java long primitive type - not an object - and what I seem to trick TDI (or really the underlying Javascript engine) it returns a java.lang.Double which is basically removing the lower significant bits...
1.Using Java reflection - but I do not see a way of converting the long into a object this way
2.Writing a Java (jar file) wrapper - I believe this would be similar to what the complexTypeFC functionality - but I would like to avoid custom jars in my solution.
Does anybody have an idea to solve this ?
IF - and that is a big if - I have to go with solution 2 I would like to combine the 2 options - i.e. have a generic Javascript function that take the class, method and return object type as input and then uses the reflection API to actually execute the method and some generic Java code to perform the transformation from the primitive to an object. The reason for this is of course to make it reusable for all TDI'ers :-)
All ideas are welcome :-)
Regards
Franz Wolfhagen
Hi Franz,
You can do this in a very easier way.
Stephen posted about the same in his blog (https://blog.stephen-swann.co.uk/2012/02/tivoli-directory-integrator-and-long.html?m=1).
This happened because the toString() conversion within Javascript when operated on a Long object is incapable of retaining precision.
So, what you can do is wrap the String.valueOf() method inside a Java class and then use it in TDI.
package itimutil;
import com.ibm.itim.apps.Request;
public class util{
public static String getRequestID(Request request){
if ( request != null )
return String.valueOf(request.getID())
else
return "";
}
}
Use the same method in TDI -
var TIMProcessID = Packages.itimutil.util.getRequestID(request);
task.logmsg("INFO", "TIMProcessID: " + TIMProcessID);
Regards,
Sufyan Khan
Thanks for you code sample - but you are missing an important point - the difference between java.lang.Long (object) and long (type) - I would have had no problems handling a Long object (as described by Stephen) - but the problem handling a type long is that it is converted to JavaScript Double before you can get your hand on it - hence the trick using apache beanutils which is basically a generic version of your code to change a type into an object...

Regards
Franz Wolfhagen

Loading...