简体   繁体   中英

Error with changeSet in jenkins pipeline (Error:java.io.NotSerializableException: hudson.plugins.git.GitChangeSetList)

I have this error:

java.io.NotSerializableException: hudson.plugins.git.GitChangeSetList

when ChangeSet!=null but the strange is that the error ocurred when updating this plugin: Pipeline Shared Groovy Libraries, before this work good, i use jenkins v 2.21 and pipeline 2.4 and my code is the next:

def changeLogSets = currentBuild.rawBuild.changeSets
for (int i = 0; i < changeLogSets.size(); i++) {
   def entries = changeLogSets[i].items
   for (int j = 0; j < entries.length; j++) {
        def entry = entries[j]
        echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
        def files = new ArrayList(entry.affectedFiles)
        for (int k = 0; k < files.size(); k++) {
            def file = files[k]
            echo "  ${file.editType.name} ${file.path}"
        }
    }
}
changeLogSets= null

Jenkins jobs can be saved in mid execution, which requires them to be serialized. The contents of rawBuild cannot be serialized, so if you access this, you need to do so within a function that is prefaced with @NonCPS . Eg:

showChangeLogs()

@NonCPS
def showChangeLogs() {
  def changeLogSets = currentBuild.rawBuild.changeSets
  for (int i = 0; i < changeLogSets.size(); i++) {
     def entries = changeLogSets[i].items
     for (int j = 0; j < entries.length; j++) {
          def entry = entries[j]
          echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
          def files = new ArrayList(entry.affectedFiles)
          for (int k = 0; k < files.size(); k++) {
              def file = files[k]
              echo "  ${file.editType.name} ${file.path}"
          }
      }
  }
}

Not exactly the same code, but the same problem can be caused if you don't declare local variables before their use. https://blog.csdn.net/liurizhou/article/details/88236397

So, additionally to adding "@NonCPS", you need to add 'def' before all local variables

I want to provide another answer, piggybacking BMitch's answer. rawBuild method poses security issue and is blocked in Jenkinsfile. In newer versions currentBuild object exposes changeSets directly, so you can use the script like this

@NonCPS
def showChangeLogs() {
    def changeLogSets = currentBuild.changeSets
    for (int i = 0; i < changeLogSets.size(); i++) {
        def entries = changeLogSets[i].items
        for (int j = 0; j < entries.length; j++) {
            def entry = entries[j]
            echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
            def files = new ArrayList(entry.affectedFiles)
            for (int k = 0; k < files.size(); k++) {
                def file = files[k]
                echo "${file.editType.name} ${file.path}"
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM