[HAP-935] Serializable exception after upgrade when doing server.upload Created: 01/Jun/17  Updated: 14/Nov/17  Resolved: 29/Jun/17

Status: Resolved
Project: Jenkins Artifactory Plug-in
Component/s: Common
Affects Version/s: 2.11.0
Fix Version/s: 2.12.0

Type: Bug Priority: High
Reporter: Jordan L Assignee: Yahav Itzhak
Resolution: Fixed Votes: 3
Labels: None

Issue Links:
Dependency
Regression:
Yes

 Description   

Hi all,

I've been using jenkins and artifactory for a little while now to upload files to my artifactory server. I since did an upgrade to the jenkins plugins, and I now see the following error when I do a server.upload(upload_spec):

java.lang.UnsupportedOperationException: Refusing to marshal org.codehaus.groovy.runtime.GStringImpl for security reasons
at hudson.util.XStream2$BlacklistedTypesConverter.marshal(XStream2.java:445)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
at com.thoughtworks.xstream.converters.collections.MapConverter.marshal(MapConverter.java:79)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
Caused: java.lang.RuntimeException: Failed to serialize groovy.lang.Binding#variables for class groovy.lang.Binding
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:250)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:226)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.<init>(AbstractReflectionConverter.java:189)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:135)
at com.thoughtworks.xstream.converters.reflection.SerializableConverter.marshalUnserializableParent(SerializableConverter.java:292)
at com.thoughtworks.xstream.converters.reflection.SerializableConverter.doMarshal(SerializableConverter.java:246)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:83)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
Caused: java.lang.RuntimeException: Failed to serialize org.jfrog.hudson.pipeline.types.ArtifactoryServer#cpsScript for class org.jfrog.hudson.pipeline.types.ArtifactoryServer
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
at com.thoughtworks.xstream.converters.collections.MapConverter.marshal(MapConverter.java:79)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
Caused: java.lang.RuntimeException: Failed to serialize org.jenkinsci.plugins.workflow.cps.actions.ArgumentsActionImpl#arguments for class org.jenkinsci.plugins.workflow.cps.actions.ArgumentsActionImpl
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
at com.thoughtworks.xstream.converters.collections.ArrayConverter.marshal(ArrayConverter.java:45)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
Caused: java.lang.RuntimeException: Failed to serialize org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage$Tag#actions for class org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage$Tag
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
at hudson.XmlFile.write(XmlFile.java:170)
at org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage.saveActions(SimpleXStreamFlowNodeStorage.java:111)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution$TimingFlowNodeStorage.saveActions(CpsFlowExecution.java:1491)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.saveActions(CpsFlowExecution.java:1012)
at org.jenkinsci.plugins.workflow.graph.FlowNode.save(FlowNode.java:380)
at org.jenkinsci.plugins.workflow.graph.FlowNode.persistSafe(FlowNode.java:386)
at org.jenkinsci.plugins.workflow.graph.FlowNode.access$100(FlowNode.java:61)
at org.jenkinsci.plugins.workflow.graph.FlowNode$1.add(FlowNode.java:346)
at org.jenkinsci.plugins.workflow.graph.FlowNode$1.add(FlowNode.java:336)
at java.util.AbstractList.add(AbstractList.java:108)
at hudson.model.Actionable.addAction(Actionable.java:152)
at org.jenkinsci.plugins.workflow.job.WorkflowRun$GraphL.onNewHead(WorkflowRun.java:910)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.notifyListeners(CpsFlowExecution.java:1221)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$3.run(CpsThreadGroup.java:407)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.run(CpsVmExecutorService.java:35)
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:748)
Finished: FAILURE

It seems to be forking a thread at this point to do it all, and the main thread hangs while this one fails with this exception. Any suggestions to fix this or work around it?

Thanks



 Comments   
Comment by Eyal Ben Moshe [ 01/Jun/17 ]

Can you please share with us a sample Pipeline script that reproduces this issue? Also, which version of the Artifactory Plugin are you using?

Comment by Jordan L [ 01/Jun/17 ]

Hi Eyal, sure.

I'm using the latest 2.11.0 artifactory plugin. Jenkins version 2.46.3.

def getArtifactoryServer(String project="") {
    switch (getNodeLocation(project)) {
        default:
            return Artifactory.server("local-artifactory")
    }
}

def uploadSimpleArtifactoryModule(ArtifactoryInfo info) {
    def uploadSpec = """{
        "files": [
                {
                    "pattern": "${info.localPath}",
                    "target": "${info.repository}/${info.remotePath}",
                    "props": "${info.props}",
                    "regexp": "true"
                }
            ]
        }"""

    def server = getArtifactoryServer(info.project)
    def buildInfo = Artifactory.newBuildInfo()

    if (info.enableBuildInfo) {
        buildInfo.env.capture = true

        buildInfo.retention maxBuilds: info.maxBuilds, maxDays: info.maxDays, deleteBuildArtifacts: info.deleteBuildArtifacts

        if (info.buildNumber > -1) {
            buildInfo.setNumber("${info.buildNumber}")
        }
  
        server.upload(uploadSpec, buildInfo)   // <-- ERROR HERE
        server.publishBuildInfo(buildInfo)   // <-- Print statements confirm I don't get here
    } else {
        server.upload(uploadSpec)  //<-- Same issue if I go through this code path
    }
}

Comment by Jonathan Anning [ 08/Jun/17 ]

Morning,

We're experiencing the same behaviour with Jenkins 2.46.3 and the 2.9.2 artifactory plugin. Attached are a sample Jenkinsfile and associated groovy script that's barfing after a second Artifactory maven build:

#!/usr/bin/groovy
@Library('ops-pipeline-library') _

  properties([disableConcurrentBuilds()]) // Limit concurrent builds so that we only build one branch per project at once.
  def dockerImage = 'proj/debian:mysql55'

  node {
  // checkout sources
  stage('Checkout') {
    checkout scm
  }

  if( env.BRANCH_NAME == 'master' ) {
    masterBuild {
      name = getServiceName('pom.xml')
      version = pomVersion('pom.xml')
      image = dockerImage
    }
    continuousCFDeploy {
      name = getServiceName('pom.xml')
      version = pomVersion('pom.xml')
    }
    deleteDir()
  } else if ( env.BRANCH_NAME.startsWith('release') ) {
    releaseBuild {
      name = getServiceName('pom.xml')
      version = pomVersion('pom.xml')
      image = dockerImage
    }
    deleteDir()
  } else if( env.BRANCH_NAME.startsWith('PR-') ) {
    prBuild {
      name = getServiceName('pom.xml')
      version = pomVersion('pom.xml')
      image = dockerImage
    }
    deleteDir()
  } else {
    stage 'Duplicate Branch?'
    println "This branch should be being built by a PR build."
  }
}
#!/usr/bin/groovy
// vars/masterBuild.groovy
// USAGE: Build the master branch of a project, producing a SNAPSHOT artifact and push that to Artifactory.
// Also runs Sonarqube analysis and pushes results to Sonarqube server.

def call(body) {
    // evaluate the body block, and collect configuration into the object
    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    body()

    // now build, based on the configuration provided - example variables given in comments
    def serviceName = config.name // microservice acryonym
    def jobVersion = config.version // version('pom.xml'), 1.2.0-SNAPSHOT
    def dockerImage = config.image // proj/debian:mysql55, proj/debian:latest
    def hash = getSHA{}

    if (!serviceName){ error 'No Artifact name defined' }
    if (!jobVersion){ error 'No Version defined' }
    if (!dockerImage){ error 'No Docker Image defined' }

    // Some debuggery
    echo "Running MASTER Build for " + serviceName + " on " + NODE_NAME + "/" + EXECUTOR_NUMBER

    // specify docker
    def dockerRun = docker.image(dockerImage)

    // specify artifactory
    def artifactorySrv = Artifactory.server('artifactory')
    def artifactoryURL = 'http://artifactory.local:8081/artifactory/'
    def artifactPath = 'libs-snapshot-local/com/example'

    // specify maven settings
    def artifactoryMvn = Artifactory.newMavenBuild()
    artifactoryMvn.tool = 'mvn3'
    artifactoryMvn.opts = '-Dmaven.test.skip=true'
    artifactoryMvn.resolver releaseRepo:'libs-release', snapshotRepo:'libs-snapshot', server: artifactorySrv
    artifactoryMvn.deployer releaseRepo:'libs-release-local', snapshotRepo:'libs-snapshot-local', server: artifactorySrv

    stage('Master Build') {
      artifactoryMvn.run pom: 'pom.xml', goals: 'clean compile'
    }

    stage('Test') {
    		dockerRun.inside {
      		sh 'mvn --batch-mode -Dmaven.test.failure.ignore=true test'
    		}
    		junit 'target/surefire-reports/TEST-*.xml'
		    testreport = testStats()
        colour = setStatusColour(currentBuild.result)
    		mattermostSend icon: channel: '#jenkins_build', color: colour, message: ":robot_face: **${serviceName}** <${env.BUILD_URL}|Master branch ${jobVersion} (*${hash}*)> Built <${env.BUILD_URL}testReport/|(Test Results)>. ${testreport}"
    	}

    stage('SonarQube Analysis') {
    		def scannerHome = tool 'sonarscanner'
    		withSonarQubeEnv('sonarq') {
 		    sh "${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=com.example.${serviceName} -Dsonar.projectName=${serviceName} -Dsonar.projectVersion=${jobVersion} -Dsonar.sources='src/main/java' -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.coveragePlugin=jacoco -Dsonar.language=java -Dsonar.jacoco.reportsPath='target/jacoco.exec' -Djacoco.version=0.7.7.201606060606 -Dsonar.java.binaries='target/classes' -Dsonar.exclusions='**/*Application.java'"
		    }
    }

    stage('Push Artifact') {
      artifactoryMvn.run pom: 'pom.xml', goals: 'install', buildInfo: buildInfo // <- This is where our builds are breaking, and throwing exactly the same exception Jordan is seeing :(
      mattermostSend channel: '#jenkins_build', color: 'info', message: ":robot_face: **${serviceName}-${jobVersion}** <${artifactoryURL}${artifactPath}/${serviceName}/${jobVersion}/|Built and uploaded to Artifactory>."
    	}
    }

Comment by Arnaud Contes [ 22/Jun/17 ]

same issue here with artifactory plugin 2.11.0.
The stacktrace is similar.

Comment by Guillaume Michaud [ 22/Jun/17 ]

+1

Comment by Franz Prilmeier [ 22/Jun/17 ]

+1

Comment by Eyal Ben Moshe [ 22/Jun/17 ]

I'm unable to reproduce this exception.
The below Pipeline script works for me. It is based on the script Jordan L shared here. I simplified it a bit. Can you please see if it runs properly for you as well?
In case it does, then the the differences between the two script may lead us to the root case:

def getArtifactoryServer() {
    return Artifactory.server("SERVER_ID")
}
def props = "p1=v1;p2=v2"
    
node {
    def uploadSpec = """{
          "files": [
            {
              "pattern": "jenkins-pipeline-examples/resources/ArtifactoryPipeline.zip",
              "target": "libs-snapshot-local",
              "props": "${props}"
            },
            {
              "pattern": "jenkins-pipeline-examples/resources/ArtifactoryPipelineNoProps.zip",
              "target": "libs-snapshot-local"
            }
          ]
        }"""

    def server = getArtifactoryServer()
    def buildInfo = Artifactory.newBuildInfo()

    buildInfo.env.capture = true

    buildInfo.retention maxBuilds: 10, maxDays: 10, deleteBuildArtifacts: true
    buildInfo.setNumber("a1")
    
    server.upload(uploadSpec, buildInfo)
    server.publishBuildInfo(buildInfo)
}

Comment by Eyal Ben Moshe [ 26/Jun/17 ]

I created a snapshot version of the Artifactory Plugin, which should resolve the issue.
I'd appreciate your feedback for it.
You can see the fix in the following commit:
https://github.com/JFrogDev/jenkins-artifactory-plugin/commit/e99ee80d2efd72168b6e614d9ff52a2889bb7da7

Here's a download link for the snapshot version:
https://oss.jfrog.org/artifactory/oss-snapshot-local/org/jenkins-ci/plugins/artifactory/2.12.x-SNAPSHOT/artifactory-2.12.x-20170626.175459-23.hpi

Comment by Damien Mure [ 27/Jun/17 ]

Hi.
I also get the same issue (artifactory 5.1.0, jenkins 2.46.3, artifactory plugin 2.11.0).

java.lang.UnsupportedOperationException: Refusing to marshal org.codehaus.groovy.runtime.GStringImpl for security reasons
	at hudson.util.XStream2$BlacklistedTypesConverter.marshal(XStream2.java:445)

I managed to create 2 pipelines the show you when it crash (or not) in my cases.
The only change is in the "repo_name" definition.
working pipeline:

node {
  stage('checkout') {
    checkout scm
  }
  
  project = 'damien'                                                                                                                                                                                                                 
  artifactUrl = 'https://artifactory.intranet.atih.sante.fr'
  def repo_name = "test-${project}"

  stage('build') {
    sh "tar zcvf test-${repo_name}-latest.tgz *"
  }

  stage('publish'){
    def server = Artifactory.newServer url: "${artifactUrl}", credentialsId: '4cb107ad-308d-4528-95e7-a0b5009b4d28'

                def props = "p1=v1;p2=v2"
                        def uploadSpec = """{
                                "files": [
                                {
                                        "pattern": "*.tgz",
                                        "target": "local-sas-scansante/test-damien/",
                                        "props": "${props}"
                                }
                                ]
                        }"""

    server.upload spec: uploadSpec
  }
}

crashing pipeline:

node {
  stage('checkout') {
    checkout scm
  }
  
  project = 'damien'                                                                                                                                                                                                                 
  artifactUrl = 'https://artifactory.intranet.atih.sante.fr'
  repo_name = "test-${project}"

  stage('build') {
    sh "tar zcvf test-${repo_name}-latest.tgz *"
  }

  stage('publish'){
    def server = Artifactory.newServer url: "${artifactUrl}", credentialsId: '4cb107ad-308d-4528-95e7-a0b5009b4d28'

                def props = "p1=v1;p2=v2"
                        def uploadSpec = """{
                                "files": [
                                {
                                        "pattern": "*.tgz",
                                        "target": "local-sas-scansante/test-damien/",
                                        "props": "${props}"
                                }
                                ]
                        }"""

    server.upload spec: uploadSpec
  }
}

In both cases, my "tgz" is created with the proper name and uploaded to artifactory. But the second pipeline fails with the exception mentions above during "server.upload".

  • I did not add the "publishBuildInfo" part in these tests.
  • It seens that I need to focus on the "def" property when defining a global variable.
  • I am not able to try your Snapshot version on our Jenkins for now.

Best Regards.
Damien

Comment by Razvan Botez [ 28/Jun/17 ]

When should we expect to see this fix deployed in an official version?

Comment by Eyal Ben Moshe [ 28/Jun/17 ]

Version 2.12.0 is expected to be released during the next few days.

Generated at Wed Aug 12 01:53:15 UTC 2020 using Jira 8.5.3#805003-sha1:b4933e02eaff29a49114274fe59e1f99d9d963d7.