jenkins 并行工作流插件因 java.io.NotSerializableException : hudson. plugins.sshslaves.SSHLauncher 而失败

标签 jenkins jenkins-workflow

任何线索为什么并行会为如此简单的事情抛出序列化错误:

  branches[nodeSpec] = {
      node(nodeSpec) {
        echo("remote");
      }

我正在尝试编写一个工作流插件构建,它在我的所有节点上执行维护任务。这在今天早些时候有效,即使我执行该代码,我也会遇到以下失败。我无法理解是什么导致了问题。我知道这可能是变量使用的问题,但我认为我没有在节点关闭中使用任何变量。

如果您有任何建议,请告诉我

错误

java.io.NotSerializableException: hudson.plugins.sshslaves.SSHLauncher at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:569) at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65) at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)



代码
// Get all Nodes from Jenkins instance
def nodelist = Jenkins.getInstance().getNodes()
branches = [:]

// Iterate list -- NOTE: we cannot use groovy style or even modern java style iteration
for (int i =0; i < nodelist.size(); i++) {
   Slave node = nodelist[i]
   def nodeSpec =  node.name.toString()
   if (node.getComputer().isOnline()) {  
      println "Create Task for ${nodeSpec}"
      branches[nodeSpec] = {
          node(nodeSpec) {
            echo("remote");
          }

      }
   }
 }  

parallel branches

最佳答案

更新:从下面的评论中,我发现我误解了 NonCPS 注释的要求。如果在分支内使用方法,这对于防止出现问题是必要的,并且即使在分支执行之前使用该方法也是为了清晰起见。

我有关于它为什么起作用的工作代码和理论。

  • 隔离 Jenkins slave 对象以确保它们不会被传送到节点,因为它们不能被序列化。 (getOnlineNodeNames 将局部变量表示为字符串列表)
  • 将条件语句移到节点之外(不确定为什么会产生影响)

  • 代码
    @NonCPS
    List <String> getOnlineNodeNames() {
      List <String> nodeNames = []
      def allNodes = Jenkins.getInstance().getNodes()
      for (int i =0; i < allNodes.size(); i++) {
       Slave node = allNodes[i]
    
       if (node.getComputer().isOnline()) {  
        nodeNames.add(node.name.toString())
       }
      }
      return nodeNames
    }
    
    
    List<String> nodeList = getOnlineNodeNames()
    
    branches = [:]
    for (int i =0; i < nodeList.size(); i++) {
      String nodeName = nodeList[i]
      if(nodeName.contains("win")) {
        branches[nodeName] = { node(nodeName) { 
                 bat '''@echo off
    DoMainTasks....'''
    
           } 
        }
      } else {
        branches[nodeName] = { node(nodeName) { 
             sh '''set +x
    DoMainTasks....'''
           } 
        }
      }
    
    }
    parallel branches
    

    关于jenkins 并行工作流插件因 java.io.NotSerializableException : hudson. plugins.sshslaves.SSHLauncher 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35490182/

    相关文章:

    tomcat - 如何在 Jenkins 中创建 2 个独立的 m2 存储库

    clojure - 如何在运行时访问正在运行的 Clojure 应用程序的版本号?

    google-app-engine - mvn gcloud :deploy [Error gcloud app command exit code is: 1]

    groovy - 如何使用 Groovy API 检索 Jenkins 构建参数?

    tomcat - 是否可以使用 Jenkins 在 tomcat 中部署多个 war 文件?

    Git clone on jenkins master,复制到slave

    jenkins - 在 Jenkins Workflow 插件中获取输入批准者用户名

    groovy - 沙盒阻止我格式化字符串

    jenkins - 创建可重用的 Jenkins 管道脚本

    git - 如何使用 Jenkins DSL 插件创建多分支项目?