java.io.NotSerializableException:Jenkins管道中的sun.net.www.protocol.https.HttpsURLConnectionImpl

java.io.NotSerializableException:Jenkins管道中的sun.net.www.protocol.https.HttpsURLConnectionImpl,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,关于它意味着什么以及如何处理它有很多讨论,但是使用@NonCPS的主要解决方案似乎不起作用。以下是相关的代码: @NonCPS def restCall(String method, String resource, String data = '') { def URL url = new URL("${Params.REST_BASE_URI}/${resource}") def HttpURLConnection connection = url.openConnectio

关于它意味着什么以及如何处理它有很多讨论,但是使用
@NonCPS
的主要解决方案似乎不起作用。以下是相关的代码:

@NonCPS
def restCall(String method, String resource, String data = '') {
    def URL url = new URL("${Params.REST_BASE_URI}/${resource}")
    def HttpURLConnection connection = url.openConnection()

    withCredentials([usernamePassword(credentialsId: 'restful-api', passwordVariable: 'RA_PASS', usernameVariable: 'RA_USER')]) {
        String encoded = Base64.getEncoder().encodeToString(("${env.RA_USER}:${env.RA_PASS}").getBytes(StandardCharsets.UTF_8))
        connection.setRequestProperty("Authorization", "Basic ${encoded}");
    }

    connection.setRequestProperty("content-type", "application/json");
    connection.setRequestMethod(method)
    connection.doOutput = true

    if (data != '') {
        def writer = new OutputStreamWriter(connection.outputStream)
        writer.write(data)
        writer.flush()
        writer.close()
    }

    connection.connect();

    def statusCode =  connection.responseCode
    if (statusCode != 200 && statusCode != 201) {
        throw new Exception(connection.getErrorSteam().text)
    }

    return connection.content.text
}
请注意,它的函数上确实有
@NonCPS
。但是,执行此操作仍会产生相同的错误:

an exception which occurred:
    in field groovy.lang.Reference.value
    in object groovy.lang.Reference@1375b00
    in field WorkflowScript$_bitbucketCall_closure1.connection
    in object WorkflowScript$_bitbucketCall_closure1@b3001c
    in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@144b2a6
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@144b2a6
Caused: java.io.NotSerializableException: sun.net.www.protocol.https.HttpsURLConnectionImpl
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
    at ...

我该如何解决它呢?

事实证明,实现我的目标不需要
@NonCPS
注释。相反,我所需要做的就是确保在方法调用结束时没有仍然初始化的不可序列化变量。因此,以下方法效果良好:

def restCall(String method, String resource, String data = '') {
    def URL url = new URL("${Params.REST_BASE_URI}/${resource}")
    def HttpURLConnection connection = url.openConnection()

    withCredentials([usernamePassword(credentialsId: 'restful-api', passwordVariable: 'RA_PASS', usernameVariable: 'RA_USER')]) {
        String encoded = Base64.getEncoder().encodeToString(("${env.RA_USER}:${env.RA_PASS}").getBytes(StandardCharsets.UTF_8))
        connection.setRequestProperty("Authorization", "Basic ${encoded}");
    }

    connection.setRequestProperty("content-type", "application/json");
    connection.setRequestMethod(method)
    connection.doOutput = true

    if (data != '') {
        def writer = new OutputStreamWriter(connection.outputStream)
        writer.write(data)
        writer.flush()
        writer.close()
    }

    connection.connect();

    def statusCode =  connection.responseCode
    if (statusCode != 200 && statusCode != 201) {
        String text = connection.getErrorStream().text
        connection = null
        throw new Exception(text)
    }

    String text = connection.content.text
    connection = null
}

诀窍是在方法执行结束之前显式设置
connection=null

我认为将方法标记为
@NonCPS
只适用于方法本身。这将不适用于
URL.openConnection()
的范围,该范围似乎不可序列化。话虽如此,我希望有人知道如何解决这个问题,因为创建RESTAPI调用的全局变量在jenkins-pipeline中会非常有用。我看到的是,您正在从NonCPS方法中调用一些管道方法。这既不受支持,也不会起作用。但是,我认为出现异常的原因不是在这里搜索,而是在未标记为NonCPS的其余代码中搜索。为了支持您,请同时提交调用代码。@我认为调用代码与此无关,因为堆栈跟踪指向
HTTPUrlConnection
类。在任何情况下,调用代码的示例都是
def result=restCall('GET','info')