web-dev-qa-db-ja.com

Jenkinsワークフローのビルド中にNotSerializableExceptionエラーを修正する方法

Jenkinsワークフロー(Jenkins 1.609.1、ワークフロー1.8)で次のコードを実行すると、「NotSerializableException」のエラーが表示されます(以下も同様)。ただし、「ビルドジョブ」を「for」スコープの外に移動すると、正常に機能します(ジョブがアクティブ化されます)。なぜこの動作になるのですか?

node('master') { 
ws('/opt/test) {
def file = "/ot.property"
def line = readFile (file)
def resultList = line.tokenize()
for(item in resultList )
  {
build job: 'testjob_1'
   }
 }
}

エラーが発生しました:

Running: End of Workflow 
Java.io.NotSerializableException: Java.util.ArrayList$Itr  
    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.doWriteObject(RiverMarshaller.Java:854)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.Java:1032)  


.....
17
oTolev

これは、build jobステップに到達するとすぐに、itemのシリアライズ不可能なresultListイテレータをシリアライズしようとしているためだと思います。シリアライズ不可能な変数の使用に関するガイダンスについては、こちらをご覧ください。

https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md#serialization-of-local-variables

ワークフロープラグインを使用して安全に反復するための回避策として、Cスタイルのループを使用する必要があります。代わりにこれを試してください:

for ( int i = 0; i < resultList.size; i++ ) {
  etc...
19
Brian Ray

CloudBees Platform Help page によると:

設計上、パイプラインはSerializableオブジェクトのレコードのみを保持できます。中間変数をシリアル化できないオブジェクトで保持する必要がある場合は、それをメソッドに隠して、このメソッドに@NonCPSで注釈を付ける必要があります。

そのため、@NonCPSヘルパーメソッドを使用して、コードを関数に変換する必要があります。

関連するジェンキンスのバグ: JENKINS-27421

5
kenorb