have the next field which I try to send in slack results of my job
} finally {
sh(script: 'ls -lah')
slack.jobResultNotification(currentBuild.result, '#some_channel',null,null,null,'https://hooks.slack.com/services/XXXXXX/XXXXXX/XXXXXXX')
}
}
But everytime I get
java.lang.NullPointerException: Cannot invoke method getSecret() on null object
Function for slack Notification ( I only added the important parts of my code)
def jobResultNotification(String buildStatusParam, String channel = "#some_channel",
String jobName=null,
Number buildNumber=null, String buildUrl=null,
String credentialsId="SLACK_WEBHOOK_URL") {
def jobNameParam = jobName != null && jobName != "" ? jobName : env.JOB_NAME
def buildUrlParam = buildUrl != null && buildUrl != "" ? buildUrl : env.BUILD_URL
def buildNumberParam = buildNumber != null && buildNumber != "" ? buildNumber : env.BUILD_NUMBER
def common = new com.Common()
cred = common.getCredentialsById(credentialsId)
hook_url_parsed = cred.getSecret().toString()
}
and for creds
def getCredentialsById(String credsId, String credsType = 'any') {
def credClasses = [ // ordered by class name
sshKey : com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey.class,
cert : com.cloudbees.plugins.credentials.common.CertificateCredentials.class,
password : com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class,
any : com.cloudbees.plugins.credentials.impl.BaseStandardCredentials.class,
dockerCert: org.jenkinsci.plugins.docker.commons.credentials.DockerServerCredentials.class,
file : org.jenkinsci.plugins.plaincredentials.FileCredentials.class,
string : org.jenkinsci.plugins.plaincredentials.StringCredentials.class,
]
return com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
credClasses[credsType],
jenkins.model.Jenkins.instance
).findAll { cred -> cred.id == credsId }[0]
}
Related
I created a Jenkins folder which has multiple jobs in it. I've also defined some variables in the folder itself. How can I check if the folder has a variable defined? I tied
import jenkins.model.*
private def getBuildJob(final String folder) {
def jobFolder = null
for (f in Jenkins.instance.getAllItems(AbstractItem.class)) {
if (f.fullName == folder) {
jobFolder = f
break
}
}
return jobFolder
}
node("linux-ubuntu") {
stage("test") {
def folder = getBuildJob("MyFolderName")
println folder.hasVariable("MY_VARIABLE")
}
}
But I get
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: com.cloudbees.hudson.plugins.folder.Folder.hasVariable() is applicable for argument types: (java.lang.String) values: [MY_VARIABLE]
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:153)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:161)
If you are using the folder-properties plugin you can use the following script.
#NonCPS
def checkVar() {
def folderName = "Folderycr"
def propToCheck = "YCRPROP"
def folderItem = Jenkins.instance.getAllItems(com.cloudbees.hudson.plugins.folder.AbstractFolder.class).find{ (it.name == folderName) }
println folderItem.getProperties().each { prop ->
if(prop instanceof com.mig82.folders.properties.FolderProperties){
prop.getProperties().each{
if(it.key == propToCheck) {
println "Prop is available. Vale is : " + it.value
}
}
}
}
}
node("linux-node") {
stage("Run test") {
checkVar()
}
}
I want to use Jenkins' active choices reactive parameter to use Groovy script to show all branches in the repository.
I have the following code sample to get all branches of a repository and since that there are hundreds of branches, I want the default to be master branch.
Even though I specifically inserted the defaultBranch variable, it shows the first item as the default and not the branch I written to.
Code:
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import jenkins.model.Jenkins
def git_url ="url"
def getAllBranches(url, credentialID, activeChoice = false, defaultBranch = 'master') {
def jenkinsCredentials = CredentialsProvider.lookupCredentials(
com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey,
Jenkins.instance
);
def key = jenkinsCredentials.findResult { it.id == credentialID ? it.privateKey : null }
if( !key ) {
return 'Error: credentials not found'
}
Process process = ['ssh-agent','bash','-c', "echo '" + key + "' | ssh-add - 2> /dev/null && git ls-remote -t -h " + url].execute()
def out = new StringBuilder()
def err = new StringBuilder()
process.consumeProcessOutput( out, err )
process.waitFor()
if( err.size() > 0 ) return err
if( out.size() > 0 ) {
def branches = out.readLines().collect { it.split()[1].replaceAll('refs/heads/', '') }
if( activeChoice ) {
def defaultBranchIndex = branches.indexOf(defaultBranch)
if( defaultBranchIndex >= 0 ) branches.set(defaultBranchIndex, defaultBranch + ':selected')
}
return branches
}
}
return getAllBranches(git_url, "efa7bed9-56a0-42ac-8fa3-a68fe7700801")
You have set default for activeChoice to false in the getAllBranches method and do not set while calling it, thus the if-branch that adds the :selected is never entered.
I changed activeChoice method's value from false to true and it solved my issue:
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import jenkins.model.Jenkins
def git_url ="url"
def getAllBranches(url, credentialID, activeChoice = true, defaultBranch = 'master') {
def jenkinsCredentials = CredentialsProvider.lookupCredentials(
com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey,
Jenkins.instance
);
def key = jenkinsCredentials.findResult { it.id == credentialID ? it.privateKey : null }
if( !key ) {
return 'Error: credentials not found'
}
Process process = ['ssh-agent','bash','-c', "echo '" + key + "' | ssh-add - 2> /dev/null && git ls-remote -t -h " + url].execute()
def out = new StringBuilder()
def err = new StringBuilder()
process.consumeProcessOutput( out, err )
process.waitFor()
if( err.size() > 0 ) return err
if( out.size() > 0 ) {
def branches = out.readLines().collect { it.split()[1].replaceAll('refs/heads/', '') }
if( activeChoice ) {
def defaultBranchIndex = branches.indexOf(defaultBranch)
if( defaultBranchIndex >= 0 ) branches.set(defaultBranchIndex, defaultBranch + ':selected')
}
return branches
}
}
return getAllBranches(git_url, "efa7bed9-56a0-42ac-8fa3-a68fe7700801")
I have the following two Classes which work just fine locally in groovy, but once I use them with Jenkins Shared Libraries I run into some issues.
./Template.groovy
class Template {
String arch
String type
def body = {}
Template(type, arch, body) {
this.arch = arch
this.type = type
this.body = body
}
}
./TemplateBook.groovy
import Template
class TemplateBook {
def templates = []
TemplateBook() {
def template = new Template("test", "lnx", { args -> sh('echo "Hello World!"'); sh("echo Test"); sh("echo $args")})
templates.push(template)
}
def getTemplate(type, arch) {
def template
for (def i = 0; i < templates.size(); i++) {
if (templates[i].arch == arch && templates[i].type == type) {
template = templates[i].getBody()
i = templates.size()
}
}
return template
}
}
Using the Template.body directly works just fine (locally and on Jenkins), but using the TemplateBook.getTemplate() only executes the first line of the closure (body).
def templateBook = new TemplateBook()
def body = templateBook.getTemplate("test", "lnx")
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = this
body("test")
Output:
Hello World!
def template = new Template("type", "arch", { args -> sh('echo "Hello World!"'); sh("echo Test"); sh("echo $args")})
def body2 = template.body
body2.resolveStrategy = Closure.DELEGATE_FIRST
body2.delegate = this
body2("test")
Output:
Hello World!
Test
test
I am trying to get the commitID/revision in changeSet in Jenkins. And here is my code:
The commitId I got is null but I can get the revision from the summary under the Changes page when the build finished.
def project = hudson.model.Hudson.instance.getItem(project_name)
def buildnum = some_number
build = project.getBuildByNumber(buildnum)
def upstreamBuilds = build.getUpstreamBuilds()
upstreamBuilds.each() { key, value ->
def prj = key;
def num = value;
build = prj.getBuildByNumber(num);
}
def changeSet = build.changeSet
if(changeSet != null) {
def hadChanges = false
changeSet.each() { cs ->
hadChanges = true
println(cs.author)
println(cs.commitId)
println(cs.msgAnnotated)
}
}
How can I get the correct commitId from changeSet of the build?
The application works just fine, but after grails clean it starts throwing an error if I execute grails war or grail web-app:
|Loading Grails 2.4.3
|Configuring classpath
.
|Environment set to production
.................................
|Packaging Grails application
..
|Compiling 18 source files
.Error
|
Compilation error: startup failed:
General error during class generation: NPE while processing BcvjobService.groovy
groovy.lang.GroovyRuntimeException: NPE while processing BcvjobService.groovy
at org.codehaus.groovy.classgen.AsmClassGenerator.visitClass(AsmClassGenerator.java:252)
at org.codehaus.groovy.control.CompilationUnit$16.call(CompilationUnit.java:805)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1047)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:583)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:561)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:538)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:517)
at org.codehaus.groovy.tools.FileSystemCompiler.compile(FileSystemCompiler.java:59)
at org.codehaus.groovy.tools.FileSystemCompiler.doCompilation(FileSystemCompiler.java:215)
at org.codehaus.groovy.ant.Groovyc.runCompiler(Groovyc.java:1161)
at org.codehaus.groovy.ant.Groovyc.compile(Groovyc.java:1212)
at org.codehaus.groovy.grails.compiler.Grailsc.compile(Grailsc.java:78)
at org.codehaus.groovy.ant.Groovyc.execute(Groovyc.java:827)
...
Googling didn't help in the least, so I can't even understand where to start, and any help would be greatly appreciated.
Here is BcvjobService.groovy:
package bcvapp
import grails.transaction.Transactional
import groovy.lang.Closure;
import groovy.io.FileType
import groovy.util.AntBuilder
import java.awt.event.ItemEvent;
import java.util.List;
import java.util.regex.Pattern;
import grails.util.Mixin
import grails.util.Holders
import org.codehaus.groovy.grails.web.context.ServletContextHolder as SCH
#Transactional
#Mixin(ServiceCategory)
class BcvjobService {
def mailService
def holderService
def servletContext = SCH.servletContext
def String absPath = getAbsPath()
def String configPath = servletContext.getRealPath("/pipeline/bcvrun.prj.xml")
def outputMap = [:]
def prepareDirectory(Bcvjob job, String sessionId, List fileList, List directionList, Integer queueSize){
def configFile = new File (configPath)
def defaultConfig = new XmlParser().parse(configFile)
// Create directory structure
def inputLine = defaultConfig.BCV_Input
def input = inputLine.text().replaceAll(Pattern.compile('[\\.\\/\\\\]'), '')
def outputLine = defaultConfig.BCV_Output
def output = outputLine.text().replaceAll(Pattern.compile('[\\.\\/\\\\]'), '')
def folderPath = "${absPath}${sessionId}"
def inputPath = folderPath + "/" + input
def outputPath = folderPath + "/" + output
addResultsPath(sessionId, outputPath)
inputLine[0].value = inputPath
outputLine[0].value = outputPath
def inpath = defaultConfig.InPath // why there are two almost identical lines in bcv config?
inpath[0].value = inputPath
new File (inputPath).mkdirs()
new File (outputPath).mkdir()
new File(outputPath + "/simple_results.html").createNewFile()
File res = new File(outputPath + "/simple_results.html")
if (queueSize > 2 ){
res << ("Your task was submitted at ${new Date()}<p>")
res << ("Waiting in queue..<p>")
res << ("Please, bookmark this page to see the results later. Refresh the page to check if they are ready.")
}
else {
res << ("Your task was submitted at ${new Date()}<p>")
res << ("Running..<p>")
res << ("Please, bookmark this page to see the results later. Refresh the page to check if they are ready.")
}
res << ("<script>")
res << ("var interval = setInterval('location.reload()', '30000');")
res << ("</script>")
for (f in fileList){
new File (outputPath + "/" + f.getOriginalFilename().replaceAll(Pattern.compile('\\..*'), '').replaceAll("\\s+", "_")).mkdir()
}
uploadFiles(inputPath, fileList)
// Write custom configuration file
def vocabulary = defaultConfig.Vocabulary
def vocabularyPath = vocabulary[0].text().substring(0, vocabulary[0].text().lastIndexOf("/")+1)
def vocabularyName = job.vocabulary.replaceAll(/\s+/, "_")
vocabulary[0].value = vocabularyPath + vocabularyName + ".seq.fas"
def reads = defaultConfig.READS.find{'READS'}
reads.children.clear()
def counter = 0
for (f in fileList){
def stringDirection
if (directionList.get(counter) == "r"){
stringDirection = "reverse"
}
else stringDirection = "forward"
reads.appendNode('Read', [name:f.getOriginalFilename().replaceAll("\\s+", "_")]).appendNode('Direction', stringDirection)
counter++
}
def taxdb = defaultConfig.Database
if (job.taxdb == "full"){
taxdb[0].value = "all"
}
else if (job.taxdb == "named isolates"){
taxdb[0].value = "named"
}
def distance = defaultConfig.DistanceThreshold
distance[0].value = job.distance.toFloat()
def email = defaultConfig.Email
email[0].value = job.email
def mode = defaultConfig.Mode
mode[0].value = "PIPELINE"
def writer = new StringWriter()
def printer = new XmlNodePrinter(new PrintWriter(writer))
printer.with {
preserveWhitespace = true
expandEmptyElements = true
}
printer.print(defaultConfig)
def result = writer.toString()
new File(folderPath + "/bcvrun.prj.xml").write(result)
return outputPath
}
def Closure getWaitingPipeline = {Bcvjob job ->
def queueSize = Bcvjob.countByDateCreatedLessThanEquals(job.dateCreated) + Stapjob.countByDateCreatedLessThanEquals(job.dateCreated)
if(queueSize > 2){
println (" bcv waiting in queue; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
while (queueSize > 2){ // 1 running task + our task
sleep(5000)
queueSize = Bcvjob.countByDateCreatedLessThanEquals(job.dateCreated) + Stapjob.countByDateCreatedLessThanEquals(job.dateCreated)
}
println (" bcv finished waiting in queue; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
def res = new File(getResults(job.sessionId)).newWriter()
res.write("Your task was submitted at ${new Date()}<p>")
res.write("Running..<p>")
res.write("Please, bookmark this page to see the results later. Refresh the page to check if they are ready.")
res.close()
}
def returnCode = runPipeline(job.sessionId)
println (" bcv waiting pipeline finished; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
if (returnCode != 143){
zipResults(job.sessionId)
println (" bcv waiting results zipped; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
}
if (returnCode == 0){
if (job.email) {
sendResults(job.email, job.sessionId)
println (" bcv waiting results sent; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
}
}
else {
if (job.email) {
sendLogs(job.email, job.sessionId)
println (" bcv bad news sent; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
}
else if (returnCode != 143) {
sendLogs(job.sessionId) // send to weidewind
}
else {
println (" user left; sessionId ${job.sessionId} ")
}
}
def sessionId = job.sessionId
job.delete(flush:true)
holderService.setDone(sessionId)
}
def Closure getPipeline = {Bcvjob job ->
def returnCode = runPipeline(job.sessionId)
println (" bcv pipeline finished; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
if (returnCode != 143){
zipResults(job.sessionId)
println (" bcv results zipped; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
}
if (returnCode == 0){
if (job.email) {
sendResults(job.email, job.sessionId)
println (" bcv results sent; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
}
}
else {
if (job.email) {
sendLogs(job.email, job.sessionId, returnCode)
println (" bcv bad news sent; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
}
else if (returnCode != 143) {
sendLogs(job.sessionId) // send to weidewind
}
else {
println (" user left; sessionId ${job.sessionId} ")
}
}
def sessionId = job.sessionId
job.delete(flush:true)
holderService.setDone(sessionId)
}
private def addResultsPath(String sessionId, String outputPath){
outputMap.putAt(sessionId, outputPath)
}
def runPipeline(String sessionId){
println (" going to run bcv pipeline, sessionId ${sessionId}")
def command = "perl /store/home/popova/Programs/BCV_pipeline/pipeline.pl ${absPath}${sessionId} bcvrun.prj.xml >${absPath}pipelinelog.txt >2${absPath}pipelinerr.txt"// Create the String
holderService.procs[sessionId] = command.execute() // Call *execute* on the string
holderService.procs[sessionId].consumeProcessOutput( System.out, System.err ) //31.10
holderService.procs[sessionId].waitFor() // Wait for the command to finish
def exitValue = holderService.procs[sessionId].exitValue()
println "return code " + exitValue
holderService.deleteProc(sessionId)
return exitValue
}
def uploadFiles(String uploadPath, List fileList){
for (f in fileList){
if(f instanceof org.springframework.web.multipart.commons.CommonsMultipartFile){
def fileName = f.getOriginalFilename().replaceAll("\\s+", "_")
new FileOutputStream(uploadPath + "/" + fileName).leftShift( f.getInputStream() )
} else {
log.error("wrong attachment type [${f.getClass()}]");
}
}
}
def uploadSequenceFiles(String uploadPath, List fileList){
for (f in fileList){
if(f instanceof org.springframework.web.multipart.commons.CommonsMultipartFile){
def fileName = f.getOriginalFilename().replaceAll("\\s+", "_")
new FileOutputStream(uploadPath + "/" + fileName.replaceAll(Pattern.compile('\\..*'), '') + "/" + fileName).leftShift( f.getInputStream() )
} else {
log.error("wrong attachment type [${f.getClass()}]");
}
}
}
def sendResults(String email, String sessionId) {
def results = getZipResults(sessionId)
println "going to send files, sessionID ${sessionId} resultsPath ${results} time ${System.currentTimeMillis()}"
mailService.sendMail {
multipart true
to email
subject "BCV results"
body "Thanks for using BCV!\n Here are your results. \n Have a nice day!"
attachBytes 'results.zip','application/zip', new File(results).readBytes()
}
}
def sendExampleResults(String email, String folderName){
def results = getStorePath() + folderName + "/results.zip"
println "going to send files, folderName ${folderName} resultsPath ${results} time ${System.currentTimeMillis()}"
mailService.sendMail {
multipart true
to email
subject "Example BCV results"
body "Thanks for using BCV!\n Here are your example results. \n Have a nice day!"
attachBytes 'results.zip','application/zip', new File(results).readBytes()
}
}
def sendLogs(String email, String sessionId) {
//def logs = "${absPath}${sessionId}logfile"
def results = getZipResults(sessionId)
println "going to send logs, sessionID ${sessionId} logPath ${logs} time ${System.currentTimeMillis()}"
mailService.sendMail {
multipart true
to email
subject "BCV failed"
body "We are very sorry, but something has gone amiss. Here are some of your results, though."
attachBytes 'results.zip','application/zip', new File(results).readBytes()
}
//just in case there is no results at all and results.zip does not exist. Todo: catch mailService or zip exception
//else user left, auto-termination
mailService.sendMail {
multipart true
to "weidewind#gmail.com"
subject "BCV failed"
body "Achtung! email: ${email}, sessionId: ${sessionId}"
}
mailService.sendMail {
multipart true
to "weidewind#gmail.com"
subject "BCV failed"
body "Achtung! email: ${email}, sessionId: ${sessionId}"
attachBytes 'results.zip','application/zip', new File(results).readBytes()
}
println (" bcv bad news sent to webmaster; sessionId ${job.sessionId} time ${System.currentTimeMillis()}")
}
def sendLogs(String sessionId){
//just in case there is no results at all and results.zip does not exist. Todo: catch mailService or zip exception
mailService.sendMail {
multipart true
to "weidewind#gmail.com"
subject "BCV failed"
body "Achtung! sessionId: ${sessionId}"
}
println (" bcv bad news sent to webmaster; sessionId ${sessionId} time ${System.currentTimeMillis()}")
}
def zipResults(String sessionId){
def output = getOutput(sessionId)
def results = getZipResults(sessionId)
println "going to zip files, sessionID ${sessionId} time ${System.currentTimeMillis()}"
println (output)
def p = ~/.*\.(svg|html|with_names|cluster\.fasta)/
def filelist = []
def outputDir = new File(output)
outputDir.eachDir { chrom ->
def chromDir = new File(chrom.absolutePath)
chromDir.eachFileMatch(FileType.FILES, p){ tree ->
def splittedPath = tree.absolutePath.split('/')
println ("going to add ${splittedPath[splittedPath.size()-2]}/${splittedPath[splittedPath.size()-1]} from ${output} to zip list; sessionId ${sessionId}")
filelist.add("${splittedPath[splittedPath.size()-2]}/${splittedPath[splittedPath.size()-1]}")
}
}
filelist.add("simple_results.html")
println("results will be placed here ${results}")
def zipFile = new File("${results}")
new AntBuilder().zip( basedir: output,
destFile: zipFile.absolutePath,
includes: filelist.join( ' ' ) )
}
def getResults (String sessionId){
return outputMap.getAt(sessionId) + "/simple_results.html"
}
def getOutput(String sessionId){
return outputMap.getAt(sessionId)
}
def getZipResults(String sessionId){
return outputMap.getAt(sessionId) + "/results.zip"
}
def getExampleFolderName(List fileList){
def exampleFileNames = []
for (f in fileList){
exampleFileNames.add(f.name)
}
exampleFileNames.sort()
def folderName = ""
for (f in exampleFileNames){
folderName = folderName + (f.replaceAll(Pattern.compile('\\..*'), ''))
}
println folderName
return folderName
}
def checkInput(Bcvjob job, List fileList){
String errorMessage = ""
if (!job.validate()) {
errorMessage = "Some errors occured: "
job.errors.each {
errorMessage += "<p>" + it + "</p>"
}
//if (!isFloat(job.distance) || job.distance.toFloat() < 0 || job.distance.toFloat() > 0.1){
if ( job.distance < 0 || job.distance > 0.1){
errorMessage += "<p> Maximum distance must not be less than 0 or more than 0.1 </p>"
}
if (job.errors.hasFieldErrors("email")){
errorMessage += "<p>Your e-mail does not seem valid </p>"
}
if (job.errors.hasFieldErrors("files") || (fileList.size() == 0 & job.isExample == "false")){
errorMessage += "<p>Select at least one file </p>"
}
}
if (fileList.size() > 10){
errorMessage += "<p>Please, do not select more than 10 files at once. </p>"
}
if (job.isExample == "false"){
for (f in fileList) {
def name = f.getOriginalFilename()
int dot= name.lastIndexOf(".");
if (name.substring(dot+1) != "ab1"){
errorMessage += "<p>Unsupported extension: ${name} </p>"
}
def bytes = f.getBytes()
if (bytes[0] != 'A' || bytes[1] != 'B' || bytes[2] != 'I' || bytes[3] != 'F' || !(bytes[4]+bytes[5] >= 101)){
errorMessage += "<p>Not ABI: ${name} </p>"
}
}
}
return errorMessage
}
def isFloat(String value)
{
try
{
Float.parseFloat(value);
return true;
} catch(NumberFormatException nfe)
{
return false;
}
}
def getAbsPath(){
return Holders.config.absPath
}
def getStorePath(){
return Holders.config.storePath
}
def talkWork(){
ServiceCategory.talkWork()
}
def talkQueue(){
ServiceCategory.talkQueue()
}
}