java.io.NotSerializableException: sun.net.www.protocol.https.HttpsURLConnectionImpl в конвейере Дженкинса - PullRequest
0 голосов
/ 08 ноября 2018

Существует множество дискуссий о том, что это значит и что с этим делать, однако основное решение использования @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 ...

Как я могу это решить?

1 Ответ

0 голосов
/ 10 декабря 2018

Оказывается, аннотация @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 перед выполнением метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...