web-dev-qa-db-fra.com

Pipeline Jenkins Erreur Java.io.NotSerializableException Java.util.regex.Matcher même avec @NonCPS

J'utilise @NonCPS devant ma fonction Jenkinsfile qui effectue une correspondance d'expression régulière et je reçois toujours l'erreur Java.io.NotSerializableException Java.util.regex.Matcher même avec l'annotation @NonCPS.

Notez qu'il appelle la fonction plusieurs fois et que l'exception ne se produit qu'une fois la correspondance établie.

Voici mon code:

@NonCPS
def extractEndTime(logLine) {
    def MY_REGEX = /.*(20[0-9]{2}-[0-9]{2}-[0-9]{2}).([0-9]{2}:[0-9]{2}:[0-9]{2}).*\"\w+\"\sthe text\s(\w+)\./
    m = (logLine =~ TEST_LOGLINE_END_REGEX)
    if (m.count) {
        return [m[1],m[2],m[3]]
    } else {
        return null
    }
}

La sortie lors de la construction de jenkins:

GitHub has been notified of this commit’s build result
Java.io.NotSerializableException: Java.util.regex.Matcher
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.Java:860)
    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(ObjectOutputStream.Java:344)
    at Java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.Java:333)
    at Java.util.HashMap.writeObject(HashMap.Java:1354)
    at Sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:497)
    at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.Java:271)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.Java:976)
    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.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(ObjectOutputStream.Java:344)
    at com.cloudbees.groovy.cps.SerializableScript.writeObject(SerializableScript.Java:26)
    at Sun.reflect.GeneratedMethodAccessor145.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:497)
    at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.Java:271)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.Java:976)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.Java:967)
    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.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.doWriteSerializableObject(RiverMarshaller.Java:967)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.Java:854)
    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(ObjectOutputStream.Java:344)
    at Java.util.HashMap.internalWriteEntries(HashMap.Java:1777)
    at Java.util.HashMap.writeObject(HashMap.Java:1354)
    at Sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:497)
    at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.Java:271)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.Java:976)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.Java:854)
    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.AbstractObjectOutput.writeObject(AbstractObjectOutput.Java:58)
    at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.Java:111)
    at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.Java:132)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.Java:433)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.Java:412)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.Java:357)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.Java:78)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.Java:236)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.Java:224)
    at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.Java:63)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:266)
    at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.Java:112)
    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.Java:28)
    at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:511)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:266)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617)
    at Java.lang.Thread.run(Thread.Java:745)
Caused by: an exception which occurred:
    in field delegate
    in field closures
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@42b37962
Finished: FAILURE
15
Daniel Park

Probablement en raison de la variable m variable ..__, essayez de la limiter avec def comme ceci:

def m = (logLine =~ TEST_LOGLINE_END_REGEX)

Sans def, une variable est créée dans une liaison de script globale et existe donc après la sortie de la méthode.

24
izzekil

Jenkins exige que toutes les variables soient sérialisables, car l’état du pipeline est périodiquement sauvegardé sur le disque en cas d’interruptions similaires à un redémarrage du serveur. Cette fonctionnalité permet aux pipelines de conserver leur état et de continuer même après le redémarrage du serveur. Les variables de type Matcher ne sont pas sérialisables et nécessitent du travail supplémentaire de la part du développeur.

De jenkinsci/pipeline-plugin Sérialisation des variables locales :

Cependant, l'approche la plus sûre consiste à isoler l'utilisation de l'état non sérialisable dans une méthode marquée avec l'annotation @NonCPS. Une telle méthode sera être traité comme «natif» par le moteur Pipeline et ses variables locales jamais sauvé. 

L'exemple de code fourni:

@NonCPS
def version(text) {
  def matcher = text =~ '<version>(.+)</version>'
  matcher ? matcher[0][1] : null
}

Des informations supplémentaires sur ce matériel peuvent être trouvées sur Pipeline Groovy Plugin Technical Design , ils abordent ici plus de détails techniques et le comportement des méthodes marquées avec @NonCPS.

Les scripts de pipeline peuvent marquer les méthodes désignées avec l'annotation @NonCPS. Celles-ci sont ensuite compilées normalement (à l'exception des contrôles de sécurité sandbox ) Et se comportent donc comme des méthodes «binaires» à partir de Java Plate-forme, Groovy Runtime ou Jenkins core ou plug-in. @NonCPS les méthodes peuvent utiliser en toute sécurité des objets non-Serializable en tant que variables locales, bien qu’ils ne doivent pas accepter de paramètres non sérialisables ni renvoyer ni stocker des valeurs non sérialisables. Vous ne pouvez pas appeler régulier Méthodes (transformées en CPS), ou étapes de pipeline, à partir d'une méthode @NonCPS, il est donc préférable d’utiliser certains calculs avant de passer un résumé au script principal. Notez en particulier que @Overrides des méthodes définies dans les classes binaires, telles que Object.toString (), devrait en général être marqué @NonCPS car il sera généralement binaire code les appelant.

Voir: Sérialisation des variables locales Et Conception technique d'un plug-in Groove Pipeline

13
SINGULARITY

Juste pour plus de clarté, ce qui suit a fonctionné pour moi.

Le travail supplémentaire pour le développeur, à titre d'exemple, voir le code ci-dessous.

my.Parameter n'est pas sérialisable

donc je fais une méthode, sans un def et l'annote @NonCPS et appelle cela depuis le bloc de nœud

  node('MySys') {
    echo 'hello'
    avoidCPS()
    echo 'finished'
  }

  @NonCPS
  avoidCPS () {
    // use my.Parameter here
    my.Parameter p = new my.Parameter()
    ... do some more ...
  }
2
Mike