关于它的含义和处理方法的讨论很多,但是使用@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 ...
我该如何解决?
答案 0 :(得分:3)
结果是,不需要@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
。