Jenkins Workflow plugin Maven "No compiler is provided in this environment" - maven

I have a Workflow job with the following Groovy code segment:
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn install"
When I run it I get the error:
[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
I have installed JDK in "Jenkins > Manage Jenkins > Configure System" and gave the name "JAVA_HOME". When a run a "Freestyle project" job to test the installation:
echo "JDK: $JAVA_HOME"
The output is good:
JDK: /var/lib/jenkins/tools/hudson.model.JDK/JAVA_HOME
I also tried restarting Jenkins but it didn't help. Please advise.
FYI, I started to use the following fix by changing the Workflow code like this:
def mvnHome = tool 'M3'
def javaHome = tool 'JAVA_HOME'
sh "JAVA_HOME=$javaHome $mvnHome/bin/mvn install"
I don't know if this is a correct solution or a hack.

Your final script looks correct. Maven generally requires a full JDK to run, not just a JRE. If your build slave does not already have one in its $PATH then you can use the tool step to modify $PATH and/or $JAVA_HOME to point to it.

This question is old but Jenkins recommends doing it this way:
withEnv(["JAVA_HOME=${ tool 'JAVA_HOME' }", "PATH+MAVEN=${tool 'M3'}/bin"]) {
sh "mvn install"
}
You can see it here: Jenkins Pipeline Examples. It works for me

Related

sbt dist works in terminal but not with Jenkins as shell script

I am completely new to both sbt and Jenkins. I am trying to construct a build plan using Jenkins piplelines. The following commands run just fine within shell script: sbt compile & sbt package
However, sbt dist does not work. I get the error not a valid command
What is puzzling me, I can run the command from terminal just fine.
For what its workth, here is the contents of jenkinsfile (I know sbt dist should be in build, but I am still experimenting):
pipeline {
agent any
stages {
stage('Build') {
parallel {
stage('Build') {
steps {
sh 'echo "Compiling... "'
sh 'sbt compile'
}
}
stage('Deploy') {
steps {
sh 'echo "Deploying... "'
sh 'echo "packaging.. "'
sh 'sbt dist'
}
}
}
}
}
}
Jenkins 2.89.1, sbt tried both: 0.13 and 1.0.x
I see now from comments that you are working on Play application, so it is clear now where the dist task comes from.
In Jenkins first thing that you need to make when you running SBT tasks is that you have loaded to SBT your build.xml of your project. In your shell script it is not actually visible whether you are in the root project folder or not.
Also Jenkins has integration with SBT better then just running it through shell script. You need to add this plugin to Jenkins first. Look at the attached screenshot, where part of one of my Jenkins projects is shown:
There is a special kind of build step in Jenkins. In your project configuration you should see it under the "Build step" dropdown:
I believe you should start from there. If you still need to run through shell script make sure you also cd /path/to/your/project folder before running SBT commands.
I accepted #Alexander Arendar answer, as it is the correct answer. I just want to elaborate on how I got it right, so it can be useful for others.
The answer as #Alexander mentioned is If you still need to run through shell script make sure you also cd /path/to/your/project folder before running SBT commands. I was actually doing that. But what I was completely oblivious to, is that cd to directory and running sbt dist must be withiin the same jenkins step. I was doing that in two separate steps, and ending up running sbt dist in the original directory.
One worthy note is, cd to project was needed only for sbt dist since it comes with Play. Standard sbt commands (e.g.: sbt compile) were running fine outside the play project directory.

nohup: failed to run command `sh`: No such file or directory

I have the following pipeline script in Jenkins:
node {
withMaven(globalMavenSettingsFilePath: '/my/path/apache-maven-3.2.2/conf/settings.xml', jdk: 'JDK 1.8.0u92', maven: 'apache-maven-3.2.2', mavenSettingsFilePath: '/my/path/apache-maven-3.2.2/conf/settings.xml') {
sh '/my/path/apache-maven-3.2.2/bin/mvn clean install'
}
}
For this, I am getting:
nohup: failed to run command `sh`: No such file or directory
ERROR: script returned exit code -2
Why is this?
I am sure that the path to my Maven installation is correct. When I run a job without the pipeline, Maven builds with no errors and I can see that it uses the same path.
This might be the result of modifying PATH.
Check your script and Global Properties and remove modifications to PATH. It is now recommended to use PATH+extra instead. It would still be picked up, but without breaking actual PATH.
Related issue on Jenkins: https://issues.jenkins-ci.org/browse/JENKINS-41339
In the end, I used shell instead of sh and it worked. No idea why, they don't have a proper API.
I would suggest to use it like this:
withMaven(
maven: 'M3',
mavenSettingsConfig: 'maven-settings-for-the-task',
mavenLocalRepo: '.repository') {
// Run the maven build
sh "mvn clean install"
}
Apart from that I would not use absolute paths to global settings.xml nor to user settings.xml. I would prefer using usage of "Config File Provider Plugin" which has the advantage to have the settings.xml on Master and available on all nodes.
See also the documentation: https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Maven+Plugin
This error comes when you are trying to run script copied from windows machine to unix machine.
YOU need to change the format to unix using : dos2unix <scriptname.sh> and the run your script in unix ./<scriptname.sh>

Unable to set maven in groovy script

I am using groovy script in jenkins pipeline job and I need maven to execute my stage.
I do not have control of .profile as it is running on slave. I need to set the Maven in my groovy script so that I can run man clean compile.
maven is located at /opt/runtime/apache-maven-3.3.3/bin/mvn.
I am very new to groovy and want to know how to use this.
You can do something like this:
// Maven location
def mvnHome = tool name: 'maven 3_3_9', type: 'hudson.tasks.Maven$MavenInstallation'
env.MAVEN_HOME = mvnHome
// Begin Compile
stage concurrency: 1, name: 'compile'
sh '''${MAVEN_HOME}/bin/mvn clean compile'''
Please note that the tool name comes from the Maven configuration you have defined in the Global Tool Configuration page.

Jenkins: How to use a variable from a pre-build shell in the Maven "Goals and options"

I have a Maven job in Jenkins. Before the actual build step I have an "Execute shell" pre-build step. In that shell I set a variable:
REVISION=$(cat .build_revision)
I would like to use that variable in the Maven build job in "Goals and options":
clean install -Drevision=${REVISION}
But that does not work! The "Drevision" is set to "${REVISION}" not the actual value of ${REVISION}. Output:
Executing Maven: -B -f /home/gerrit/.jenkins/jobs/<job_name>/workspace/pom.xml clean install -Drevision=${REVISION}
It works with Jenkins environment variables:
clean install -Dbuild=${BUILD_NUMBER}
It sets "Dbuild" to the actual build number. Output:
Executing Maven: -B -f /home/gerrit/.jenkins/jobs/<job_name>/workspace/pom.xml clean install -Dbuild=54
My question: How to use a shell variable in Maven "Goals and options"??
EDIT:
I tried using Jenkins EnvInject Plugin to "Inject environment variables" after the pre-build shell, and my variable is now accessible by e.g. post-build shells, but it is still not available in Maven "Goals and options".
Then it is possible to set "Inject environment variables to the build process" using the EnvInject Plugin, which actually makes those variables available in Maven "Goals and options", but those are set right after SCM checkout, i.e. before pre-build steps, and do not support expression evaluations.
You're on the right track here, but missed a third feature of the EnvInject-Plugin: The "Inject environment variables" build step that can inject variables into following build steps based on the result of a script or properties.
We're using the EnvInject plugin just like that; A script sets up a resource and communicates its parameters using properties that are then propagated by the plugin as environment variables.
i.e. setting up a temporary database for the build:
I had a very similar problem, trying to compute a build version and inject it into the build. After running into all the same issues (not expanding, etc), I used the "Generate environment variables from script" option, which interprets the output as tag=value pairs into Jenkins variables. The script :
#generate a version code that is high enough to surpass previously published clients
val=`expr 150000 + $BUILD_NUMBER`
echo VERSION_CODE=$val
After this, I was able to inject $VERSION_CODE into maven as follows :
-Dbuild.vercode=${VERSION_CODE}
Hope that works for you.
This issue is caused by a bug in the Jenkins Maven Project Plugin as detailed in this bug report opened on 2012-06-22. The plugin has not yet been fixed as of version 2.1.
A fix has been proposed for the Maven Project Plugin, but has not yet been integrated. Here is the link to the pull request: https://github.com/jenkinsci/maven-plugin/pull/14
If you build the plugin yourself with the pull request patch applied, the variables are injected and made available to the "goals and options" field as expected.
I see there is an accepted answer, but for a newbie in Jenkins I found it hard to grasp it all. That's why I would add a bit more detail in this answer and show how I did it.
As #jjungnickel suggested you need to have EnvInject Plugin installed for Jenkins. Then in the Build section > Add build step you'll get option "Inject environment variables".
Basically the idea is:
Add variables you want to access later to a file (might be added by a shell script or it could be file from the file system).
Inject the file with the variables.
Use the variables.
Here a sample setup:
Since I want to use them in maven goal I need to check the Inject Build Variables checkbox.
Then at the end of the build I remove the file just because I want to keep the environment as it was before the build.
I think your best shot is to try the EnvInject plugin for this along with your initial pre-scm step.
You run the pre-scm as you already do.
You use the env inject to load the file for the main job's build steps
Consider loading your file's content (properties format) or execute a script which will load the file as you want and make a variable available for the rest of the job with the "Prepare an environment for the run" option.
I hope this helps.
I needed to resolve the variables before the injection was done so I put this in script content:
Example: (note it doesn't seem possible to simply export variables here so I wrote to files and the help section in jenkins seems to indicate this is expected)
git ls-tree --name-only -r ${sha1} | grep -v -c "*\.md" > diff.bak
git diff origin/master --shortstat | grep "1 files changed" && echo 1 > count.bak || echo 0 > count.bak
I then added this in the groovy script, using the output files I can create a map:
def procDiff = "cat $WORKSPACE/diff.bak".execute()
def procCount = "cat $WORKSPACE/count.bak".execute()
def diff = procDiff.text
def count = procCount.text
print "string val = $diff and count = $count "
if ("0".equals(diff) || !"1".equals(count)){
def map = ["GOAL": "clean verify"]
return map
} else {
def map = ["GOAL": "clean"]
return map
}
Then I could reference $GOAL in my maven build to conditionally trigger a "clean" or a "clean verify" based on the type of PR raised.

Jenkins executing maven from incorrect path

This happens for both: maven projects, and freestyle projects, when maven target is envoked, it tries to execute mvn using absolute path.
[MY-Job] $ tools/Maven/Jenkins_Private_Maven/bin/mvn -f cc/pom.xml -Ddeploy_env=xxx.dev.prv -Dbranch=dev -D-Dsmdist.target=/opt/builds -U clean test -DtestGroups=unit,delegate -Do verride:server=xxx.dev.prv
FATAL: command execution failed
java.io.IOException: Cannot run program "tools/Maven/Jenkins_Private_Maven/bin/mvn" (in directory "workspace/MY-Job"): java.io.IOException: error=2, No such file or directory
I can see that mvn is installed at user's home :
/home/jenkins/tools/Maven/Jenkins_Private_Maven/bin/mvn
but it's trying to run it from the workspace:
/home/jenkins/workspace/MY-Job/tools/Maven/Jenkins_Private_Maven/bin/mvn
Add the default maven installation under (Jenkins -> configuration)
Goto the failing job and make sure you choose the default maven installation from dropdown
Run the job. Success!
Are you sure you have set up Maven in Jenkins -> configuration like this
I have hunch you have a accidental **"."** current directory reference somewhere in your maven set up.
This looks like an auto installed Maven by Jenkins. In which case the previous answers are not correct.
It would seem in this occasion that you have not specified a "remote fs root" for your slave in the salve setup - later versions of Jenkins flag not setting this up correctly as an error.
in Jenkins 2.43:
Manage Jenkins -> Global Tool Configuration -> Maven

Resources