Use #Grab in Jenkins pipeline script - jenkins-pipeline

We are trying to use some custom helper functions from a .jar library in our Jenkinsfile. To achieve this, we want to use the #Grab annotation from groovy/grape. Our Jenkinsfile looks like this:
#Grab('com.company:jenkins-utils:1.0')
import com.company.jenkinsutils.SomeClass
pipeline {
...
}
When trying to run the pipeline, we get the following error message:
java.lang.RuntimeException: No suitable ClassLoader found for grab
I already tried specifying #GrabConfig(systemClassLoader = true), however to no success. I suppose is has to do with the pipeline scripts running in the sandbox mode? Is there any way to make this work?

Related

How to include a resource in micronaut graalvm native image with gradle buildNativeLambda

As described in this guide I am using ./gradlew buildNativeLambda command to generate zip file containing graalvm native image. I am facing a problem described in this thread so wanted to include resource by passing -H:IncludeResources to my command like below:
./gradlew buildNativeLambda -H:IncludeResources="com/amazonaws/partitions/endpoints.json"
Unfortunately, its failing with Unknown command-line option '-H'. How can I pass this to gradle task?
Seems like the right way to do it is though build.gradle file like below:
graalvmNative {
binaries {
main {
buildArgs "-H:IncludeResources=\"com/amazonaws/partitions/endpoints.json\""
}
}
}

Gradle Replace token

I am using gradle filtering to replace a token in one log4j.xml using below code.
import org.apache.tools.ant.filters.ReplaceTokens
task copylog4jEnvSpecific(type:Copy){
from("$config_dir/"+"$env")
into("$webAppDir/WEB-INF/classes")
include "**/log4j.xml"
filter(ReplaceTokens, tokens: [LOG_HOME: project.rootDir])
}
but I am getting an error saying
Execution failed for task ':copylog4jEnvSpecific'.
Could not copy file 'C:\Users\<>\rws\conf\<>\configuration\dev\log4j.xml' to 'C:\Users\<>\rws\build\WebContent\WEB-INF\classes\log4j.xml'.
Need more information here. Run your build with --stacktrace maybe we can get some more info there.
I presume C:\Users\<>\rws is your project path?
When do you run the task? maybe the build directory does not exist yet?
As well what is creating WebContent\WEB-INF\classes\ ?
You can make sure that your task is executed after the build task with:
copylog4jEnvSpecific.dependsOn build

How to import a custom class from Jenkins pipeline script?

I want to be able to load a custom class from my pipeline script.
Specifically, I'm looking at having my pipeline script checkout fetch the Jenkinsfile and a number of .groovy files in the same directory (eg classA.groovy, classB.groovy)
I would expect to be able to have my pipeline script simply do a:
import classA
import classB
However, this results in an "Unable to resolve class" error.
I've tried the "pipeline-classpath-step-plugin", but it requires the main pipeline script to call its new step "AddToClassPath" and then load in an additional file which then can import.
Is there some other way to modify (or even to see) the classpath the script is running with?

groovy.lang.MissingPropertyException: No such property: manager for class: Script1

I am trying to invoke Groovy inside Hudson (using groovy plugin) to get some properties for our build. But I am getting this exception:
groovy.lang.MissingPropertyException: No such property: manager for class: Script1
I get this with the following line:
def buildNUmber = manager.build.number
This happens when I run as an inline command within Jenkins as well as using a script:
I tried the solution below, but it fails during the declaration itself (line two):
Binding binding = new Binding();
binding.setVariable("manager", manager);
GroovyShell shell = new GroovyShell(binding);
shell.evaluate(new File("d:/dev/others/hudson/userContent/ScriptStuff.groovy").text);
The above is run using: Groovy command. And when I run the build it errors and complains about the line - binding.setVariable("manager", manager);
When I use the Groovy script file, then it complains about:
def buildNumber = manager.build.number
Both errors are :
groovy.lang.MissingPropertyException: No such property: manager for class: Script1
Tried everything mentioned in this thread as well:
I am using Hudson 2.2.1 and Groovy 2.1.3. What could be wrong?
manager is provided by certain Groovy script plugins, but not all. To make your script generic, use the Jenkins/Hudson API instead:
import hudson.model.*
def build = Thread.currentThread().executable
def buildNumber = build.number
...
Just in case it helps, if you are using the 'Execute System Groovy Script', you don't need to use the 'manager' variable. This worked for me -
def workspace = build.getEnvVars()["WORKSPACE"]
One of the reasons groovy.lang.MissingPropertyException: is thrown when you are using a variable outside of its scope or you haven't defined that variable.
Maybe I'm missing some part of your code, but where do you define the manager? If that's the complete Groovy script, you're trying to bind a variable which isn't declared anything, so it isn't surprising that it fails.
Just define a manager it that's what you want, like:
def manager = "my manager" // probably not what you want
This should solve your current error.

JVM-based scripting language with Maven dependency resolution

I am looking for a simple way write short shell scripts that call into jar files.
Having to keep track of (and installing) all those jar files for the runtime classpath partly defeats the purpose using a script (as opposed to building a runnable jar file in Eclipse). I'd like Maven (or something equivalent) to manage this.
Image:
#!/usr/bin/the-cool-shell
use org.apache.commons/lang/3.0.0
use org.json/json
import org.json.*;
new JSONObject("{}");
And this should get the required artifacts from Maven automatically (at basically zero overhead after downloading it for the first time).
What are my options?
If you were using Groovy and Groovy Shell you could be using the Grape infrastructure.
#!/usr/bin/env groovy
#Grab( 'log4j:log4j:1.2.14' )
import org.apache.log4j.Level
import org.apache.log4j.Logger
def logger = Logger.getLogger(GroovyShell.class)
Logger.rootLogger.level = Level.INFO
logger.info 'I am using the Log4j library by using Grape'
As for your exact example this would work:
#!/usr/bin/env groovy
#Grapes([
#Grab('org.apache.commons:commons-lang3:3.0'),
#Grab('org.json:json:20090211')
])
import org.json.*
new JSONObject('{}')
In this case I was using the Groovy syntax but ordinary Java syntax is also fine.
Taken from the Javadoc of #Grapes annotation:
Sometimes we will need more than one grab per class, but we can only add
one annotation type per annotatable node. This class allows for multiple
grabs to be added.
You could try Gradle, it's a build management tool, but it uses Groovy for its build scripts, and it uses the Maven dependency model. So your script could be a Gradle 'build' script, that just did something different than building software.

Resources