Reputation: 761
I am new in Jenkins. The codes below is to construct a simple command and pass this command , which is java.lang.String
type, to the next job. My question is that the data exchange between this Jenkins-pipeline and the Jenkins-job 'email_job' only contains string (java.lang.String
) which should be serializable. However, this script throw the exception java.io.NotSerializableException: java.time.format.DateTimeFormatter
.
If removing the build-step in the below script, this Jenkins-pipeline works fine. My Jenkins version is 2.138.4
. Any clues?
import java.net.URLEncoder
// Jenkins pipeline
pipeline {
agent any
stages {
stage('main') {
steps {
println '------------------ main-stage ------------------'
script {
def r_ptr = java.time.LocalDateTime.now()
def l_ptr = r_ptr.minusDays(14) as java.time.LocalDateTime
def fmt4time = 'yyyy-MM-dd HH:mm:ss'
def fmt2cnv = java.time.format.DateTimeFormatter.ofPattern(fmt4time) // formatter for conversion
def l_str4tz = l_ptr.format(fmt2cnv)
def r_str4tz = r_ptr.format(fmt2cnv)
l_str4tz = '2020-02-18 00:00:00'
r_str4tz = '2020-03-18 00:00:00'
//
def ip4server = '127.0.0.1'
def qry_info = []
def __qry = ''
__qry = URLEncoder.encode(l_str4tz, 'UTF-8').replace('+', '%20')
__qry = "start_time=${__qry}"
qry_info.push(__qry)
__qry = URLEncoder.encode(r_str4tz, 'UTF-8').replace('+', '%20')
__qry = "end_time=${__qry}"
qry_info.push(__qry)
def qry_opts = qry_info.join('&')
def __cmd = ''
__cmd = "curl --get http://${ip4server}/dsb4bbu?" + qry_opts
build (
job: 'email_job',
parameters: [
string(name: 'param01', value: "11112222"),
string(name: 'cmd', value: "${__cmd}"),
]
)
}
}
}
}
}
Upvotes: 0
Views: 1665
Reputation: 27766
Pipeline restricts all variables to Serializable types (see Best Practices for Scalable Pipeline Code).
I suggest to extract the code that prepares the build parameters into a function annotated with @NonCPS
(prevent CPS transformation). Within this function you are not restricted to serializable variables, but there is a different limitation, you cannot call pipeline steps and other functions that don't have @NonCPS
annotation, except for some simple ones like echo
(see Pipeline CPS method mismatches).
I think it's also a better code style to only have high-level code within the pipeline{}
block (single level of abstraction principle).
import java.net.URLEncoder
// Jenkins pipeline
pipeline {
agent any
stages {
stage('main') {
steps {
println '------------------ main-stage ------------------'
script {
build (
job: 'email_job',
parameters: [
string(name: 'param01', value: "11112222"),
string(name: 'cmd', value: prepareCmd()),
]
)
}
}
}
}
}
@NonCPS
String prepareCmd() {
def r_ptr = java.time.LocalDateTime.now()
def l_ptr = r_ptr.minusDays(14) as java.time.LocalDateTime
def fmt4time = 'yyyy-MM-dd HH:mm:ss'
def fmt2cnv = java.time.format.DateTimeFormatter.ofPattern(fmt4time) // formatter for conversion
def l_str4tz = l_ptr.format(fmt2cnv)
def r_str4tz = r_ptr.format(fmt2cnv)
l_str4tz = '2020-02-18 00:00:00'
r_str4tz = '2020-03-18 00:00:00'
//
def ip4django = '127.0.0.1'
def qry_info = []
def __qry = ''
__qry = URLEncoder.encode(l_str4tz, 'UTF-8').replace('+', '%20')
__qry = "start_time=${__qry}"
qry_info.push(__qry)
__qry = URLEncoder.encode(r_str4tz, 'UTF-8').replace('+', '%20')
__qry = "end_time=${__qry}"
qry_info.push(__qry)
def qry_opts = qry_info.join('&')
return "curl --get http://${ip4server}/dsb4bbu?" + qry_opts
}
Upvotes: 2