1. ホーム
  2. json

[解決済み] Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap

2022-11-18 12:52:52

質問

解決済み : ありがとうございます。 回答 S.Richmondより。私はアンセットする必要がありました すべて の保存されたマップを groovy.json.internal.LazyMap 型の変数を無効化することを意味します。 envServersobject を使用した後です。

追加 : このエラーを検索している人はJenkinsのパイプラインステップを使うことに興味があるかもしれません。 readJSON を使うことに興味があるかもしれません。 ここで .


Jenkins Pipelineを使って、ユーザーからの入力をjson文字列としてジョブに渡そうとしています。Pipelineはslurperを使用してこれを解析し、私は重要な情報を選び出します。そして、その情報を使って、1つのジョブを異なるジョブパラメータで複数回、並行して実行します。

以下のコードを追加するまでは "## Error when below here is added" を追加するまでは、スクリプトは問題なく実行されます。それ以下のコードも単独で実行されます。しかし、組み合わせると以下のようなエラーになります。

トリガーされたジョブは呼び出され、正常に実行されますが、以下のエラーが発生し、メインジョブが失敗することに注意する必要があります。このため、メインジョブはトリガーされたジョブのリターンを待つことはありません。I の周りをtry/catchしてください。 build job: の周りでtry/catchすることもできますが、私はメインジョブがトリガーされたジョブの終了を待つようにしたいのです。

どなたか助けていただけませんか?もしこれ以上情報が必要なら、私に知らせてください。

乾杯

def slurpJSON() {
return new groovy.json.JsonSlurper().parseText(BUILD_CHOICES);
}

node {
  stage 'Prepare';
  echo 'Loading choices as build properties';
  def object = slurpJSON();

  def serverChoices = [];
  def serverChoicesStr = '';

  for (env in object) {
     envName = env.name;
     envServers = env.servers;

     for (server in envServers) {
        if (server.Select) {
            serverChoicesStr += server.Server;
            serverChoicesStr += ',';
        }
     }
  }
  serverChoicesStr = serverChoicesStr[0..-2];

  println("Server choices: " + serverChoicesStr);

  ## Error when below here is added

  stage 'Jobs'
  build job: 'Dummy Start App', parameters: [[$class: 'StringParameterValue', name: 'SERVER_NAME', value: 'TestServer'], [$class: 'StringParameterValue', name: 'SERVER_DOMAIN', value: 'domain.uk'], [$class: 'StringParameterValue', name: 'APP', value: 'application1']]

}

エラーです。

java.io.NotSerializableException: groovy.json.internal.LazyMap
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
    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)
    at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
    at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at java.util.LinkedHashMap.internalWriteEntries(Unknown Source)
    at java.util.HashMap.writeObject(Unknown Source)
...
...
Caused by: an exception which occurred:
    in field delegate
    in field closures
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@5288c

どのように解決するのですか?

今日、私自身この問題に遭遇し、いくつかのブルートフォースを通じて、解決方法と潜在的な理由の両方が判明しました。

おそらく、その理由から始めるのが最善でしょう。

Jenkinsは、すべてのジョブを中断、一時停止、およびサーバーの再起動によって再開できるパラダイムを持っています。これを達成するために、パイプラインとそのデータは完全にシリアライズ可能でなければなりません - つまり、すべての状態を保存できる必要があるのです。同様に、ビルドのノードとサブジョブの間でグローバル変数の状態をシリアライズできる必要があります。これは、あなたと私が考えていることであり、追加のビルドステップを追加した場合にのみ発生する理由です。

何らかの理由で、JSONObject はデフォルトではシリアライズ可能ではありません。私は Java 開発者ではないので、悲しいことに、このトピックについてこれ以上多くを語ることはできません。GroovyとJenkinsにどの程度適用できるかはわかりませんが、これを適切に修正する方法についての回答はたくさんあります。 この投稿を見る を参照してください。

どのように修正するのか

もし方法を知っているならば、おそらくJSONObjectを何らかの方法でシリアライズ可能にすることができます。そうでなければ、グローバル変数がその型でないことを確認することで解決できます。

をアンセットしてください。 object の設定を解除するか、メソッドでラップして、そのスコープがノードグローバルでないようにしてください。