Task is getting terminated

Which IIQ version are you inquiring about?

Version 8.1

Share all details related to your problem, including any error messages you may have received.

I am running this rule through the task and getting this error:

The 4e91eeab8eaf4475b21c86eedc6652d1 task failed to execute
sailpoint.tools.GeneralException: StackOverflowError

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule created="" id="" language="beanshell" modified="" name="">
  <Description>
		    Rule to remove negative assignment.
		</Description>
  <Signature returnType="String">
    <Inputs>
      <Argument name="config">
        <Description>
			  The current user's locale
			</Description>
      </Argument>
      <Argument name="taskResult">
        <Description>
			  The current user's locale
			</Description>
      </Argument>
    </Inputs>
  </Signature>
  <Source>
  import sailpoint.object.*;
  import sailpoint.api.*;        
  import sailpoint.object.RoleAssignment;  
  import sailpoint.object.QueryOptions;
  import sailpoint.object.Filter;
  import sailpoint.object.Identity;
  import java.util.Iterator;
  import sailpoint.api.SailpointContext;
  import java.util.List; 
  import java.util.ArrayList;
  import java.util.Arrays;
  import sailpoint.tools.Util;
  import sailpoint.object.Attributes;
  import sailpoint.object.Identity;
  import org.apache.commons.logging.LogFactory;
  import org.apache.commons.logging.Log;
  import sailpoint.object.ProvisioningPlan;
  import sailpoint.object.ProisioningPlan.AccountRequest;
  import sailpoint.object.ProvisioningPlan.AttributeRequest;
  import sailpoint.api.TaskManager;
  import sailpoint.object.TaskResult;


  

  List idenNames = new ArrayList();
  int recordCounter = 0;
  
  QueryOptions qo = new QueryOptions();

  qo.setCloneResults(true); 

  qo.addFilter(Filter.and(Filter.eq("iiqStatus", "Terminated"),Filter.eq("orgStatus", "Hired")));

  Iterator  it = context.search(Identity.class, qo); 
  while (it.hasNext()) { 

    List bundleNames = new ArrayList();    
    Identity identityObj = it.next();
    recordCounter++;

    if (identityObj !=null) 

    {
      List roleAssignments = identityObj.getRoleAssignments();
     


      if (roleAssignments!= null) 
      {  

        for(RoleAssignment role : roleAssignments)


        {  
          if(role !=null &amp;&amp; role.isNegative()) 

          { 
            String bundle = role.getRoleName();
            
            negroleAssignments = identityObj.getRoleAssignments(bundle);
            Bundle bundl = context.getObjectByName(Bundle.class,bundle);
            boolean flag = false;

           
            if(negroleAssignments != null) 
            {
              for(RoleAssignment negrole : negroleAssignments)
              {
                
                negrole.setNegative(flag);


              }

              idenNames.add(identityObj.getName());

            }          
          } 

        } 
      }

      
      context.saveObject(identityObj);
      
      if(0 == (recordCounter % 10) )
      {
        context.commitTransaction();
      }
      
      

    }

  }
  context.commitTransaction();
  
  if(idenNames != null &amp;&amp; !idenNames.isEmpty()) 
  {
    taskResult.addMessage(idenNames.size()+ " Identities updated for negative role assignment ");
  }
  else
  {
    taskResult.addMessage(" No Identities were found for negative role assignment ");
  }



  return  taskResult;


  </Source>
</Rule>

This should be very straight forward as long there are no issues with the rule. Please share more error details or run the rule via debug to see if that gives any more information to find if there are any issues with the code in the rule.

@venus It runs perfectly fine when I run through debug. But when I run through task I get these error:
Exception: [StackOverflowError]
sailpoint.tools.GeneralException: StackOverflowError
at sailpoint.persistence.HibernatePersistenceManager.commitTransaction(HibernatePersistenceManager.java:558)
at sailpoint.persistence.ClassPersistenceManager.commitTransaction(ClassPersistenceManager.java:207)
at sailpoint.server.InternalContext.commitTransaction(InternalContext.java:560)
at sailpoint.api.TaskManager.runSync(TaskManager.java:991)
at sailpoint.api.TaskManager.runSync(TaskManager.java:764)
at sailpoint.scheduler.JobAdapter.execute(JobAdapter.java:128)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)

Unable to close TaskResult: Remove Negative Role Assignment

Unable to close TaskResult: Remove Negative Role Assignment

Do you have to call context.commitTransaction(); twice in your rule? Do you mind sharing the complete rule?

A stack overflow occurs if the call stack pointer exceeds the stack bound. The call stack may consist of a limited amount of address space.

Please take a look at : https://community.sailpoint.com/t5/IdentityIQ-Articles/IdentityIQ-8-0-and-commitTransaction-while-using-an-iterator/ta-p/143225
and use the 2nd or 3rd fix.

The solution you are using is loading all Identity objects (based on your filter) in memory and this takes a lot of memory. Using the IncrementalObjectIterator is way better memory management wise. The IdIterator is also a good option, when there are a lot of objects to update.

– Remold

2 Likes

@venus Here it is:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule >
  <Description>
		    Rule to remove negative assignment.
		</Description>
  <Signature returnType="String">
    <Inputs>
      <Argument name="config">
        <Description>
			  The current user's locale
			</Description>
      </Argument>
      <Argument name="taskResult">
        <Description>
			  The current user's locale
			</Description>
      </Argument>
    </Inputs>
  </Signature>
  <Source>
  import sailpoint.object.*;
  import sailpoint.api.*;        
  import sailpoint.object.RoleAssignment;  
  import sailpoint.object.QueryOptions;
  import sailpoint.object.Filter;
  import sailpoint.object.Identity;
  import java.util.Iterator;
  import sailpoint.api.SailpointContext;
  import java.util.List; 
  import java.util.ArrayList;
  import java.util.Arrays;
  import sailpoint.tools.Util;
  import sailpoint.object.Attributes;
  import sailpoint.object.Identity;
  import org.apache.commons.logging.LogFactory;
  import org.apache.commons.logging.Log;
  import sailpoint.object.ProvisioningPlan;
  import sailpoint.object.ProisioningPlan.AccountRequest;
  import sailpoint.object.ProvisioningPlan.AttributeRequest;

  

  List idenNames = new ArrayList();
  int recordCounter = 0;
  
  QueryOptions qo = new QueryOptions();

  qo.setCloneResults(true); 

  qo.addFilter(Filter.and(Filter.eq("iiqStatus", "Terminated"),Filter.eq("orgStatus", "Terminated")));
  Iterator  it = context.search(Identity.class, qo); 
  while (it.hasNext()) { 

    List bundleNames = new ArrayList();    
    Identity identityObj = it.next();
    recordCounter++;

    if (identityObj !=null) 

    {
      List roleAssignments = identityObj.getRoleAssignments();
     


      if (roleAssignments!= null) 
      {  

        for(RoleAssignment role : roleAssignments)


        {  
          if(role !=null &amp;&amp; role.isNegative()) 

          { 
            String bundle = role.getRoleName();
            
            negroleAssignments = identityObj.getRoleAssignments(bundle);
            Bundle bundl = context.getObjectByName(Bundle.class,bundle);
            boolean flag = false;

           
            if(negroleAssignments != null) 
            {
              for(RoleAssignment negrole : negroleAssignments)
              {
                
                negrole.setNegative(flag);


              }

              idenNames.add(identityObj.getName());

            }          
          } 

        } 
      }

      
      context.saveObject(identityObj);
      
      if(0 == (recordCounter % 10) )
      {
        context.commitTransaction();
      }
      
      

    }

  }
  context.commitTransaction();
  
  if(idenNames != null &amp;&amp; !idenNames.isEmpty()) 
  {
    taskResult.addMessage(idenNames.size()+ " Identities updated for negative role assignment ");
  }
  else
  {
    taskResult.addMessage(" No Identities were found for negative role assignment ");
  }



  return  taskResult;


  </Source>
</Rule>

HI @Rita,

As suggested by @Remold please use idIterator or IncrementalObjectIterator, also its safe to use Sailpoint.tools.Util.flushiditerator() if you are using idIterator and context.dechache(identityObj) in the finally block.

Hi @j1241,

Do you mind editing the post with the complete rule and put ``` just above the <?xml and also ``` at the bottom of the post?

This will turn the complete copy/pasted rule in Preformatted text, which makes it better to read :slight_smile:

Thanks,

Remold

@Remold Thank you. I did update the post.

1 Like