jirajira-rest-apijira-pluginjira-rest-java-apiscriptrunner-for-jira

Stackoverflow exception when transitioning an issue status to itself (tested to tested) in Jira Scriptrunner


I am using the Jira custom post function of ScriptRunner on a transition to be executed by the user from one state to itself. I am having a StackOverflow exception after executing a transition that leads to itself. I would like to transition the current status of the issue to itself. In my case, "Tested" to "Tested" and I am running into a stackoverflow exception when I do this. Here is my code in ScriptRunner. This is a custom postfunction code to be executed when the user clicks on a transition.

import com.opensymphony.workflow.WorkflowContext
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.Issue;
import com.atlassian.event.Event
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.ofbiz.core.entity.GenericValue;
import org.ofbiz.core.entity.GenericEntity;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.AbstractIssueEventListener;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.issue.ModifiedValue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
import com.atlassian.jira.issue.util.IssueChangeHolder;
import org.apache.log4j.Logger
import com.atlassian.jira.component.ComponentAccessor
import org.ofbiz.core.entity.GenericDelegator;
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager;
import com.atlassian.jira.issue.history.ChangeItemBean;
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.workflow.WorkflowManager
import com.atlassian.jira.issue.changehistory.ChangeHistoryItem
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
import com.atlassian.jira.config.SubTaskManager
import com.atlassian.jira.issue.Issue
import groovy.xml.MarkupBuilder
import com.atlassian.jira.config.properties.APKeys
import com.atlassian.jira.issue.link.LinkCollectionImpl;
import com.atlassian.jira.issue.link.IssueLink;
import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.issue.comments.CommentManager;
import com.atlassian.jira.issue.link.IssueLinkManager;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.util.ErrorCollection;
import com.atlassian.jira.util.JiraUtils;
import com.atlassian.jira.workflow.JiraWorkflow;
import com.atlassian.jira.workflow.WorkflowManager;
import com.atlassian.jira.workflow.WorkflowTransitionUtil;
import com.atlassian.jira.workflow.WorkflowTransitionUtilImpl;
import com.atlassian.jira.workflow.function.issue.AbstractJiraFunctionProvider;
import com.opensymphony.module.propertyset.PropertySet;
import com.opensymphony.workflow.WorkflowException;
import com.opensymphony.workflow.loader.ActionDescriptor;
import com.opensymphony.workflow.loader.StepDescriptor;
import com.opensymphony.workflow.spi.SimpleStep;
import com.atlassian.jira.config.ConstantsManager
import com.atlassian.jira.workflow.ImmutableWorkflowDescriptor
import com.atlassian.jira.web.action.admin.workflow.ViewWorkflowStep
import com.opensymphony.workflow.loader.ActionDescriptor
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.IssueInputParametersImpl
import com.atlassian.jira.bc.issue.IssueService.IssueValidationResult
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.workflow.WorkflowTransitionUtil
import com.atlassian.jira.workflow.WorkflowTransitionUtilFactory
def log = Logger.getLogger("atlassian-jira.log")

def defectComment= "Fix FIXSUMMARY[ISSUEKEY] has been released by USERNAME[USER]."; 
// def fixComment= "The following Defects resolved by this Fix were notified: ISSUEKEYS."; 
SubTaskManager subTaskManager = ComponentAccessor.getSubTaskManager();
List<IssueLink> links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
List<IssueLink> linksIn = ComponentAccessor.getIssueLinkManager().getInwardLinks(issue.getId())
ApplicationUser applicationUser=getCurrentUser(); 
            ArrayList<MutableIssue> issuesWithValidateError = new ArrayList<MutableIssue>();

log.warn("resolved "+ links.size()+" links in size "+ linksIn.size() +" "+ applicationUser)

for( def link in links){
    if(link.getLinkTypeId()==10022){
    log.warn("resolved "+link)

    }
}

User loggedInUser = getCurrentUser().getDirectoryUser();
 log.warn("resolved transition 1"+loggedInUser )        
WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager();
 log.warn("resolved transition 2" )     

JiraWorkflow workflow = workflowManager.getWorkflow(issue);
 log.warn("resolved transition 3" )     

List <Object> actions = workflow.getLinkedStep(issue.getStatus()).getActions(); 
 log.warn("resolved transition 4" )     


def wfd = workflow.getDescriptor();
 log.warn("resolved transition 5" )     

def actionName = wfd.getAction(transientVars["actionId"] as int).getName(); 
 log.warn("resolved transition 6 "+actionName )     

 def actionId= transientVars["actionId"] as int; 
  log.warn("resolved transition 7 "+actionId )      




transition(actionId)





void transition(int transitionToBeDone) {

log.warn("CAM 1" + issue.getIssueType().name)

  def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
  log.warn("CAM 2" )

def issueManager = ComponentAccessor.issueManager
log.warn("CAM 3" )



IssueService issueService = ComponentAccessor.getIssueService()
log.warn("CAM 4" )

def actionId = transitionToBeDone // change this to the step that you want the issues to be transitioned to
log.warn("CAM 5" )

def transitionValidationResult
log.warn("CAM 6" )

def transitionResult
log.warn("CAM 7" )

def customFieldManager = ComponentAccessor.getCustomFieldManager()
log.warn("CAM 8 " )

 
 
 transitionValidationResult = issueService.validateTransition(currentUser, issue.id, actionId,new IssueInputParametersImpl())
log.warn("CAM 9 " )

 if (transitionValidationResult.isValid()) {
 transitionResult = issueService.transition(currentUser, transitionValidationResult)
 if (transitionResult.isValid())
 { log.warn("Transitioned issue $issue through action $actionId") }
 else
 { log.warn("Transition result is not valid") }
 }
 else {
 log.warn("The transitionValidation is not valid")
 }

  
}

 ApplicationUser getCurrentUser() {
        ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getUser();
        if (user == null) {
            String defaultUser = gc.getValue("user");
            user = ComponentAccessor.getUserManager().getUserByName(defaultUser);
        }
        return user;
    }

I am getting a stackoverflow exception so my log.warn statements keep getting printed indefinitely. Here is my output. I suspect the reason for this is that my action ID (transition to be done) is leading to the same status which is Tested to Tested, it is leading to itself. I have tried having tested leading to a different status such as Follow up and it worked and I didn't have any error. Anyone knows what needs to be fixed?

2022-08-15 01:54:23,721+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 9
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 8
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 7
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 6
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 5
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 4
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 3
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 2
2022-08-15 01:54:23,706+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 1Fix
2022-08-15 01:54:23,690+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 9
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 8
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 7
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 6
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 5
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 4
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 3
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 2
2022-08-15 01:54:23,674+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 1Fix
2022-08-15 01:54:23,628+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 9
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 8
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 7
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 6
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 5
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 4
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 3
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 2
2022-08-15 01:54:23,612+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 1Fix
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 9
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 8
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 7
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 6
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 5
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 4
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 3
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 2
2022-08-15 01:54:23,581+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 1Fix
2022-08-15 01:54:23,565+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 9
2022-08-15 01:54:23,565+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 8
2022-08-15 01:54:23,549+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 7
2022-08-15 01:54:23,549+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 6
2022-08-15 01:54:23,549+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 5
2022-08-15 01:54:23,549+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 4
2022-08-15 01:54:23,549+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 3
2022-08-15 01:54:23,549+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 2
2022-08-15 01:54:23,549+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 1Fix
2022-08-15 01:54:23,534+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 9
2022-08-15 01:54:23,534+0200 https-openssl-nio-443-exec-21 WARN mouh 114x35166x1 txzbek 10.248.75.214 /secure/WorkflowUIDispatcher.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] CAM 8

Solution

  • I found the answer, I was having a recursive call inside my code. I didn't think of it as recursive because it was a static method accessed from another class. Here os the line that was causing the recursion:

     transitionResult = issueService.transition(currentUser, transitionValidationResult)
    

    Here is the correct code below:

    import com.opensymphony.workflow.WorkflowContext
    import com.atlassian.jira.issue.MutableIssue;
    import com.atlassian.jira.issue.Issue;
    import com.atlassian.event.Event
    import java.util.HashMap;
    import java.util.List;
    import org.apache.log4j.Logger;
    import org.ofbiz.core.entity.GenericValue;
    import org.ofbiz.core.entity.GenericEntity;
    import com.atlassian.jira.component.ComponentAccessor;
    import com.atlassian.jira.event.issue.AbstractIssueEventListener;
    import com.atlassian.jira.event.issue.IssueEvent;
    import com.atlassian.jira.issue.ModifiedValue;
    import com.atlassian.jira.issue.fields.CustomField;
    import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
    import com.atlassian.jira.issue.util.IssueChangeHolder;
    import org.apache.log4j.Logger
    import com.atlassian.jira.component.ComponentAccessor
    import org.ofbiz.core.entity.GenericDelegator;
    import com.atlassian.jira.issue.changehistory.ChangeHistoryManager;
    import com.atlassian.jira.issue.history.ChangeItemBean;
    import com.atlassian.jira.issue.comments.Comment
    import com.atlassian.jira.workflow.JiraWorkflow
    import com.atlassian.jira.workflow.WorkflowManager
    import com.atlassian.jira.issue.changehistory.ChangeHistoryItem
    import com.onresolve.scriptrunner.runner.util.UserMessageUtil
    import com.atlassian.jira.config.SubTaskManager
    import com.atlassian.jira.issue.Issue
    import groovy.xml.MarkupBuilder
    import com.atlassian.jira.config.properties.APKeys
    import com.atlassian.jira.issue.link.LinkCollectionImpl;
    import com.atlassian.jira.issue.link.IssueLink;
    import com.atlassian.crowd.embedded.api.User;
    import com.atlassian.jira.issue.comments.CommentManager;
    import com.atlassian.jira.issue.link.IssueLinkManager;
    import com.atlassian.jira.user.ApplicationUser;
    import com.atlassian.jira.util.ErrorCollection;
    import com.atlassian.jira.util.JiraUtils;
    import com.atlassian.jira.workflow.JiraWorkflow;
    import com.atlassian.jira.workflow.WorkflowManager;
    import com.atlassian.jira.workflow.WorkflowTransitionUtil;
    import com.atlassian.jira.workflow.WorkflowTransitionUtilImpl;
    import com.atlassian.jira.workflow.function.issue.AbstractJiraFunctionProvider;
    import com.opensymphony.module.propertyset.PropertySet;
    import com.opensymphony.workflow.WorkflowException;
    import com.opensymphony.workflow.loader.ActionDescriptor;
    import com.opensymphony.workflow.loader.StepDescriptor;
    import com.opensymphony.workflow.spi.SimpleStep;
    import com.atlassian.jira.config.ConstantsManager
    import com.atlassian.jira.workflow.ImmutableWorkflowDescriptor
    import com.atlassian.jira.web.action.admin.workflow.ViewWorkflowStep
    import com.opensymphony.workflow.loader.ActionDescriptor
    import com.atlassian.jira.bc.issue.IssueService
    import com.atlassian.jira.issue.IssueInputParametersImpl
    import com.atlassian.jira.bc.issue.IssueService.IssueValidationResult
    import com.atlassian.jira.user.ApplicationUser
    import com.atlassian.jira.workflow.WorkflowTransitionUtil
    import com.atlassian.jira.workflow.WorkflowTransitionUtilFactory
    import com.atlassian.jira.workflow.TransitionOptions
    
    def log = Logger.getLogger("atlassian-jira.log")
    
    //def defectComment= "Fix FIXSUMMARY[ISSUEKEY] has been released by USERNAME[USER]."; 
    SubTaskManager subTaskManager = ComponentAccessor.getSubTaskManager();
    List<IssueLink> linksOut = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
    List<IssueLink> linksIn = ComponentAccessor.getIssueLinkManager().getInwardLinks(issue.getId())
    ApplicationUser applicationUser=getCurrentUser(); 
    ArrayList<Issue> issuesWithValidateError = new ArrayList<Issue>();
    List<IssueLink> links = new ArrayList<IssueLink>()
    
    log.warn("resolved "+ linksOut.size()+" links in size "+ linksIn.size() +" "+ applicationUser)
    
    log.warn("THIS IS MY LINK LINKSOUT "+linksOut.size())  
    
    for( IssueLink link in linksOut){
        if(link.getDestinationObject().getIssueTypeId().equals("5")){
        log.warn("THIS IS MY LINK everything "+link.getLinkTypeId() +" "+ link.getDestinationObject().getKey())  
    
        links.add(link)
    }
        
    }
    log.warn("THIS IS MY LINK linksIn "+linksIn.size())  
    
    for( IssueLink link in linksIn){
    if(link.getDestinationObject().getIssueTypeId().equals("5")){
            log.warn("THIS IS MY LINK everything "+link.getLinkTypeId() +" "+ link.getDestinationObject().getKey())  
    
        links.add(link)
    }
    }
    
    for( IssueLink link in links){
        
        log.warn("THIS IS MY LINK MOUNA "+link + link.getDestinationObject().getKey())  
    }
      if(links.isEmpty()){
                    
                    log.warn("No linked Defect-Issues found.");
                    return;
                }
    User loggedInUser = getCurrentUser().getDirectoryUser();
     log.warn("resolved transition 1"+loggedInUser )        
    WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager();
     log.warn("resolved transition 2" )     
    
    JiraWorkflow workflow = workflowManager.getWorkflow(issue);
     log.warn("resolved transition 3" )     
    
    List <Object> actions = workflow.getLinkedStep(issue.getStatus()).getActions(); 
     log.warn("resolved transition 4" )     
    
    
    def wfd = workflow.getDescriptor();
     log.warn("resolved transition 5" )     
    
    def actionName = wfd.getAction(transientVars["actionId"] as int).getName(); 
     log.warn("resolved transition 6 "+actionName )     
    
     def actionId= transientVars["actionId"] as int; 
      log.warn("resolved transition 7 "+actionId )      
    
    
    log.warn("This is the last action "+actionName); 
    List<String> sourceObjectLinkList= new ArrayList<String>(); 
    
    def targetStatus= getTargetStatus( issue); 
     log.warn("resolved transition targetStatus "+targetStatus +"end")    ; 
    
    
    //transition(actionId, links)
      for(IssueLink link : links){
                    
        String foundID = foundActionID(link);
                    
        if(foundID == null){
                        
                        log.error("Action for Issue " + link.getKey() + " not found!");
                        issuesWithValidateError.add(link);
                        continue;
                    }
         log.warn("CAM 0 "+ foundID)    ; 
                
        Mounatransition(link.getDestinationObject(),foundID, link.getSourceObject()); 
         log.warn("links tostring "+ links.toString())    ; 
       
        sourceObjectLinkList.add(link.getDestinationObject().getKey()); 
        log.warn("MOUNA COMMENT "+link.getDestinationObject().getKey())
    
      }
    log.warn("MOUNA COMMENT "+ sourceObjectLinkList)
    String fixComment= "The following Defects resolved by this Fix were notified: ISSUEKEYS."; 
    
    fixComment = fixComment.replaceAll("ISSUEKEYS", sourceObjectLinkList.toString());
    log.warn("MOUNA CAMELIA COMMENT "+ fixComment)
    
    CommentManager commentManager = ComponentAccessor.getCommentManager();
                // add comment but do NOT fire event
    commentManager.create(issue, getCurrentUser(), fixComment, false);
    
    
    
    void Mounatransition(Issue linkedissue, String transitionToBeDone, Issue sourceObject) { 
    def defectComment= "Fix FIXSUMMARY[ISSUEKEY] has been released by USERNAME[USER]."; 
    
     log.warn("CAM 1 "+ transitionToBeDone)
    
     
    IssueService issueService = ComponentAccessor.getIssueService()
    log.warn("CAM 1 "+transitionToBeDone)
    ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
    log.warn("CAM 2")
    
    TransitionOptions transitionOptions = new TransitionOptions.Builder()
            .skipConditions()
            .skipPermissions()
            .skipValidators()
            .build()
    log.warn("CAM 3")
      int transitionToBeDoneInt = transitionToBeDone as Integer
    String status = getTargetStatus(sourceObject)  as String; 
    def constantsManager = ComponentAccessor.getConstantsManager()
    
       def statusName=constantsManager.getStatus(status).getName();
    log.warn("STatus"+status)
    
    def inputParameters = issueService.newIssueInputParameters()
    log.warn("CAM comment "+defectComment +" summary: "+sourceObject.getSummary())
    
    defectComment=defectComment.replaceAll("FIXSUMMARY", sourceObject.getSummary()); 
    log.warn("CAM comment 2"+defectComment)
    
    defectComment=defectComment.replaceAll("ISSUEKEY", sourceObject.getKey()).replaceAll("USERNAME", currentUser.getDisplayName()); 
    log.warn("CAM comment 3"+defectComment)
    
    defectComment=defectComment.replaceAll("USER", currentUser.getName()); 
    log.warn("CAM comment 4 "+defectComment)
    
    defectComment=defectComment.replaceAll("released", "set to \"" + statusName + "\" "); 
    log.warn("CAM comment 5 "+ defectComment)
    
    inputParameters.setComment(defectComment)
    IssueService.TransitionValidationResult result = issueService.validateTransition(currentUser,
            linkedissue.getId(),
            transitionToBeDoneInt,
            inputParameters,
            transitionOptions)
    log.warn("CAM 4 "+ linkedissue.getKey())
    
    try {
        if(result.isValid()) {
        log.warn("CAM 5")
    
        issueService.transition(currentUser, result)
         
    }
    
    } catch(Exception e) {
            log.warn("CAM 6 "+e)
    
          log.warn (result.getErrorCollection().getErrors());
    
    }
    
      
    }
    
     ApplicationUser getCurrentUser() {
            ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getUser();
            if (user == null) {
                String defaultUser = gc.getValue("user");
                user = ComponentAccessor.getUserManager().getUserByName(defaultUser);
            }
            return user;
        }
     def getTargetStatus(Issue issue) {
                log.warn("resolved inside target")
    
            def targetStatus = "";
            try {
                List currentSteps = (ArrayList)transientVars.get("currentSteps");
            SimpleStep simpleStep = currentSteps.get(0);
            int actionId = simpleStep.getActionId();
            int beforeStepId = simpleStep.getStepId();
            def workflow = ComponentAccessor.workflowManager.getWorkflow(issue)
            ActionDescriptor ad = workflow.getDescriptor().getAction(actionId);
            int afterStep = ad.getUnconditionalResult().getStep();
            log.warn("resolved transition target "+afterStep)
    log.warn( "resolved transition target last "+ComponentAccessor.workflowManager.getNextStatusIdForAction(issue , transientVars['actionId'] as int) )
    
             targetStatus=ComponentAccessor.workflowManager.getNextStatusIdForAction(issue , transientVars['actionId'] as int)
    def constantsManager = ComponentAccessor.getConstantsManager()
    
       def statusName=constantsManager.getStatus(targetStatus).getName();
            log.warn("resolved transition target "+targetStatus + "status name "+statusName)
    
            } catch (Exception exception)
            {
                log.error("getTargetStatus threw exception: " + exception.getMessage());
            }
            return targetStatus;
        }
    
    
         String foundActionID(IssueLink issueLink){
            
            String id = null;
                    log.warn("foundActionID 1 here")
            Issue issue=issueLink.getDestinationObject()
            List<StepDescriptor> actionDescriptorList = ComponentAccessor.workflowManager.getWorkflow(issue).getDescriptor().getSteps();
                            log.warn("foundActionID 2 here" )
    
            List<ActionDescriptor> myStepDescriptor = null;
            log.warn("foundActionID 3 here"+actionDescriptorList )
            Boolean foundAction = false;
            log.warn("foundActionID 1"+foundAction)
            for (StepDescriptor stepDescriptor : actionDescriptorList) {
                
                if (stepDescriptor.getName().equals(issue.getStatusObject().getName())){
    
                    myStepDescriptor = stepDescriptor.getActions();
                                    log.warn("foundActionID2 "+myStepDescriptor)
    
                    break;
                }
            }
    
            
            
            for(ActionDescriptor actionDescriptor : myStepDescriptor) {
                    log.warn("foundActionID3 ")
                WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager();
                JiraWorkflow workflow = workflowManager.getWorkflow(issue);
                List<ActionDescriptor>actionIDs= workflow.getLinkedStep(issue.getStatus()).getActions(); 
                log.warn("foundActionID4 "+actionIDs +"  "+String.valueOf(actionDescriptor.getId()))
                List<String> actionIdsStrings= new ArrayList<String>(); 
                for(ActionDescriptor a in actionIDs){
                actionIdsStrings.add(Integer.toString(a.getId())); 
                }
    
                if(actionIdsStrings.contains(String.valueOf(actionDescriptor.getId()))){
                    
                    id = String.valueOf(actionDescriptor.getId());
                    foundAction = true;
                    log.warn("foundActionID5 "+ id)
    
                    break;
                }
            }
            
            if(!foundAction)
                return null;
            
            return id;
        }