Which IIQ version are you inquiring about?
Version 8.3
Share all details related to your problem, including any error messages you may have received.
Hi community,
We had an integration with SAP HR working in IIQ. Due to an update in SAP Basis, we needed to also update SailPoint IIW to use the new SAP HR connector since RFC_READ_TABLE is no longer supported. Now that we have updated and adjusted the BuildMap rule as per Sailpoint support recommendation, we are getting an strange error that maybe some of you have experienced before and can help me with.
The problem is that when running the aggregation task, it fails almost every time because there is a class that we import in the BuildMap Rule that at some point during aggregation stops finding in the namespace. Find the exact error below:
âException during aggregation. Reason: java.lang.RuntimeException: sailpoint.connector.ConnectorException: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: ``import sailpoint.api.SailPointContext; import sailpoint.integration.JsonUtil; . . . ââ : Typed variable declaration : Typed variable declaration : Class: MultiFieldQueryForSPBAPI not found in namespaceâ
What is very relevant and surprising is that aggregation starts fine and runs smoothly for some accounts (it is random, sometimes 300, sometimes 4000), but usually at some points fails with this error. Once it fails, if we run aggregation again, it inmediately fails. Only way to make it work again is by restarting the tomcat (and therefore refreshing the classloaders).
From what we saw on the internet, seems to point out to something related with the beanshell / classloader cache, but donât know how to solve it.
Has anyone experienced similar issue and knows how to solve it?
Update: Rule Pasted below (cleaned and only with one parameter - personal area-, but we are querying several parameters)
import sailpoint.api.SailPointContext;
import sailpoint.integration.JsonUtil;
import sailpoint.tools.Message;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import sailpoint.tools.GeneralException;
import sailpoint.object.Script;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.lang.StringBuilder;
import sailpoint.object.ApprovalItem;
import sailpoint.object.Attributes;
import sailpoint.object.ApprovalSet;
import sailpoint.object.Application;
import sailpoint.object.Custom;
import sailpoint.object.Identity;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.Rule;
import sailpoint.object.Question;
import sailpoint.object.Workflow;
import sailpoint.object.Workflow.Variable;
import sailpoint.object.Workflow.Approval;
import sailpoint.object.Workflow.Arg;
import sailpoint.object.WorkItem;
import sailpoint.object.Script;
import sailpoint.api.SailPointContext;
import com.sap.conn.jco.AbapException;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException;
import sailpoint.connector.ConnectorException;
import sailpoint.connector.sap.tables.conditions.MultiFieldQueryForSPBAPI;
import sailpoint.connector.sap.tables.conditions.ConditionQueryStrategyForSPBAPI;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterField;
import com.sap.conn.jco.JCoParameterFieldIterator;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoStructure;
import com.sap.conn.jco.JCoTable;
import com.sap.conn.jco.JCoContext;
import sailpoint.object.EmailOptions;
import sailpoint.object.EmailTemplate;
// Get current aggregated account details
String PERNR = (String) object.get("Personal Number");
Boolean positionChange = false;
List dateConditions = new ArrayList();
DateFormat format = new SimpleDateFormat("yyyyMMdd");
String currentDate = "";
String futureDate="";
String stat2Next = object.get("STAT2_Next");
String stat2Current = object.get("STAT2_Current");
if(stat2Next != null && stat2Next.equalsIgnoreCase("Active") && stat2Current.equalsIgnoreCase("Inactive")){
String stat2NextStartDate = object.get("STAT2_Next_Start_Date");
currentDate = stat2NextStartDate != null ? stat2NextStartDate.replace("-","") : format.format(new Date());
futureDate = stat2NextStartDate != null ? stat2NextStartDate.replace("-","") : format.format(new Date());
}else{
currentDate = format.format(new Date());
}
public List retrieveSAPvalue(String tableName, String field, String identifier, String keyIdentifier, List additionalConditions){
List listFieldToGet = new ArrayList();//Campo que queremos obtener de la tabla
List listQueryFieldValues = new ArrayList(); //Lista de valores de los campos que vamos a incluir como filtro
String stringQuery = ""; //String de la query que vamos a hacer en formato ?? EQ && AND ?? EQ &&. && son los fieldvalue, ?? son los queryfield
String stringQueryField = ""; //String de los campos en los que vamos a buscar, en orden
List conditions = new ArrayList();
listFieldToGet.add(field);
separator = "|"; //Separador por defecto
fieldsSeparator = "/";
conditions.add(keyIdentifier + " = '" + identifier + "'");
conditions.addAll(additionalConditions);
//Bucle for para recorrer todas las condiciones de la lista y sacar los 3 valores que necesitamos
for (String condition : conditions){
//Separamos la string por espacio
String[] values = condition.split(" ");
//logger.debug("Valores tras split: " + values);
//comprobamos que tras separar la string por espacio nos devuelve 3 valores
if (null != values && values.length == 3){
//El primer valor es el StringQueryField, si stringQueryfiled es igual a "", concatenamos
//si stringQueryfiled es disntinto de "" concatenamos fieldsSeparator + el valor
if (stringQueryField != null && !stringQueryField.equals("")){
stringQueryField = stringQueryField + fieldsSeparator + values[0];
} else{
stringQueryField = stringQueryField + values[0];
}
//El segundo valor es el stringQuery, si es igual a "=", y stringQuery es igual a "", concatenamos "?? " + "EQ" + " &&"
//Si stringQuery es distinto de "", concatenamos " AND ?? " + "EQ" + " &&"
//Si el valor es ">=", mismo procedimiento pero "ge" en lugar de "eq", si es "<=" "le"
if (stringQuery.equals("")){
if (values[1].equals("=")){
stringQuery = stringQuery + "?? EQ &&";
}else if (values[1].equals(">=")){
stringQuery = stringQuery + "?? GE &&";
}else if (values[1].equals("<=")){
stringQuery = stringQuery + "?? LE &&";
}else{
stringQuery = stringQuery + "?? EQ &&";
logger.debug("Excepcion de query no controlada");
}
} else{
if (values[1].equals("=")){
stringQuery = stringQuery + " AND ?? EQ &&";
}else if (values[1].equals(">=")){
stringQuery = stringQuery + " AND ?? GE &&";
}else if (values[1].equals("<=")){
stringQuery = stringQuery + " AND ?? LE &&";
}else{
stringQuery = stringQuery + " AND ?? EQ &&";
logger.debug("Excepcion de query no controlada");
}
}
//El tercer valor es el listQuertFieldValue, debemos añadirlo a la lista listQueryFieldValues quitando los caracteres ''
String fieldvalue = values[2].replace("'","");
listQueryFieldValues.add(Collections.singletonList(fieldvalue));
}
}
MultiFieldQueryForSPBAPI mfq = new MultiFieldQueryForSPBAPI();
result = connector.querySAPTableWithSPBAPI(destination, tableName, listQueryFieldValues, listFieldToGet, separator, connector.getSpBapiName(), stringQuery, stringQueryField, mfq);
return result;
}
public void setProperty(String propertyName, Object value, Map object){
//logger.debug("Property: " + propertyName + " | Value: " + value);
if (value != null && !value.isEmpty()){
if(value instanceof List){
object.put(propertyName, value.get(0));
//logger.debug("not string: " + propertyName);
}else{
object.put(propertyName, value);
//logger.debug("string: " + propertyName);
}
}
//logger.debug("Successfully added property " + propertyName + " to object with value " + value);
}
// GET PERSONAL AREA DESCRIPTION
try {
List conditions = new ArrayList();
String personalArea = object.get("Personal Area");
List value = retrieveSAPvalue("T500P", "NAME1", personalArea, "PERSA", conditions);
setProperty("Personal Area Description", value, object);
} catch (Exception e) {
//logger.debug("Personal Area Description field exception: " + e);
}
Thanks a lot and best regards,
David