Down the rabbit hole -- but what a way to spend festive time :)
Not really sure what changed, but we can get around (for now) with some hacking - using "free" Rhino engine and java reflection :)
- Get access to whole Java context inside JS - follow Stefan Schnell's post about how to do that - https://community.broadcom.com/vmware-cloud-foundation/discussion/tip-use-java-classes-without-shutter-file
-
>vracli vro properties
set
-k com.vmware.scripting.javascript.allow-native-object -
v
true
- Use java reflection
- Loop over .class.getMethods() and filter by getName() .. to get references to getColumnCount, getColumnName (instance of java.lang.reflect.Method) - that actually works without step 1
- Use invoke() method to get result
- There is a problem with getColumnName since its parameter is integer but JS deals with number (and is considered double in java)
- We need full access to Java to use "java.lang.Integer(5)" here
Source code snippet:
// var md = result.getMetaData();
function getColumns(md) {
if (typeof md.getColumnCount === "undefined") { // vRO 8.18+ & SQLite
return getColumnsReflection(md);
}
var retVal = [];
var numColumns = md.getColumnCount();
// System.log("Normal way");
for (var i = 1; i <= numColumns; i++) {
var cn = md.getColumnName(i);
retVal.push(cn);
}
return retVal;
}
function getColumnsReflection(md) {
// System.log("Reflection way");
var cntMethod;
var nameMethod;
var methods = md.class.getMethods();
for (var i = 0; i < methods.length; i++) {
var mName = methods[i].getName();
if (mName === "getColumnCount") cntMethod = methods[i];
if (mName === "getColumnName") nameMethod = methods[i];
}
var retVal = [];
var numColumns = cntMethod.invoke(md);
for (var i = 1; i <= numColumns; i++) {
var intParam = java.lang.Integer(i); // this is line that requires unlocked Rhino egine Java access
var cn = nameMethod.invoke(md, intParam);
retVal.push(cn);
}
return retVal;
}