Jenkins - mvn not found - java

Hello I'm new to jenkins and getting this issue. I'm using jenkins in windows azure
mvn clean package /var/lib/jenkins/workspace/vcc#tmp/durable-b5407f14/script.sh: 2:
/var/lib/jenkins/workspace/vcc#tmp/durable-b5407f14/script.sh: mvn:
not found.
Jenkinsfiles:
node {
stage('init') {
checkout scm
}
stage('build') {
sh '''
mvn clean package
cd target
cp ../src/main/resources/web.config web.config
cp todo-app-java-on-azure-1.0-SNAPSHOT.jar app.jar
zip todo.zip app.jar web.config
'''
}
stage('deploy') {
azureWebAppPublish azureCredentialsId: env.AZURE_CRED_ID,
resourceGroup: env.RES_GROUP, appName: env.WEB_APP, filePath: "**/todo.zip"
}
}
can any body help me how can I resolve this mvn issue.
P.S I'm following this tutorial
https://learn.microsoft.com/en-us/azure/jenkins/tutorial-jenkins-deploy-web-app-azure-app-service

You may try to add maven tool to your pipeline:
tools {
maven 'M3'
}
stages {
stage('init') {
checkout scm
}
stage('build') {
sh '''
mvn clean package
cd target
cp ../src/main/resources/web.config web.config
cp todo-app-java-on-azure-1.0-SNAPSHOT.jar app.jar
zip todo.zip app.jar web.config
'''
}
stage('deploy') {
azureWebAppPublish azureCredentialsId: env.AZURE_CRED_ID,
resourceGroup: env.RES_GROUP, appName: env.WEB_APP, filePath: "**/todo.zip"
}
}

I add this line right before sh command in the build stage : def mvnHome = tool name: 'Apache Maven 3.6.0', type: 'maven'
and instead of mvn you should use ${mvnHome}/bin/mvn
thank this youtube film to help me.
pipeline{
stage('com'){
def mvnHome = tool name: 'Apache Maven 3.6.0', type: 'maven'
sh "${mvnHome}/bin/mvn -B -DskipTests clean package"
}
}

You may wanna check if Jenkins has the pipeline-maven plugin installed.
If you don't have it, search and install the pipeline-maven plugin.
Once the plugin is installed, you can use maven as follows
node{
stage('init'){
//init sample
}
stage('build'){
withMaven(maven: 'mvn') {
sh "mvn clean package"
}
}
}

Related

cucumber options are being ignored from docker run in jenkinsfile but not in local

When I launch cucumber appium tests in local with this arguments:
-ea -Dplatform=android -Dcucumber.options="--tags #mytag"
it works, but when I launch the same from a docker run, it ignores the cucumber options.
I need to launch it from a Jenkins job and run it in docker.
In my Jenkinsfile:
sh "docker run --env JAVA_OPTS='-ea -Dplatform=$platform -Dcucumber.options=$cucumberOptions'...
In the Jenkins pipeline log:
docker run --env 'JAVA_OPTS=-ea -Dplatform=android -Dcucumber.options="--tags #Check_Pricing_Payment_Org"'...
My TestTunner class:
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"src/test/resources/functionalTests/"},
plugin = {"pretty","json:target/cucumber-reports/Cucumber.json","html:target/cucumber-reports/htmlReports.html" },
glue= {"stepDefinitions"}
)
public class TestRunner {
}
Any help or clue will be appreciated. Thank you!
EDIT
As a workaround, we are now using this in our Jenkinsfile:
script {
if (env.STEP_TO_RUN.toBoolean()) {
stage('First satage') {
withMaven(maven:'mvn') {
sh 'export GOOGLE_APPLICATION_CREDENTIALS="whatevercredentials.json" && mvn clean test -Dcucumber.options="--tags #MyTag --tags #OtherTag"'
}
}
}
}
And in our CI job STEP_TO_RUN was added as a chain boolean parameter.
This way we made it work in gcloud. Hope this helps someone!

How to run jenkins pipeline relative to a sub-directory?

I have a git repository with 2 modules in it. One is SpringBoot based backend module and another one is VueJS based frontend module.
app-root
- backend
- frontend
I have a declarative style Jenkinsfile to build my backend module with relevant maven commands. I want to execute all those maven commands from inside backend directory.
One option is to use dir("backend") { ....} for all commands separately, which looks ugly to me.
Is there any other option to instruct Jenkins to execute the entire pipeline from inside a sub-directory?
I ended up with a "prepare project" stage that puts the subdirectory content into the root.
It's also probably a good idea to remove all the root contents (stage "clean") to be absolutely sure there are no leftovers from previous builds.
node {
def dockerImage
stage('clean') {
sh "rm -rf *"
}
stage('checkout') {
checkout scm
}
// need to have only 'backend' subdir content on the root level
stage('prepare project') {
// The -a option is an improved recursive option, that preserve all file attributes, and also preserve symlinks.
// The . at end of the source path is a specific cp syntax that allow to copy all files and folders, included hidden ones.
sh "cp -a ./backend/. ."
sh "rm -rf ./backend"
// List the final content
sh "ls -la"
}
stage('build docker image') {
dockerImage = docker.build("docker-image-name")
}
stage('publish docker image') {
docker.withRegistry('https://my-private-nexus.com', 'some-jenkins-credentials-id') {
dockerImage.push 'latest'
}
}
}
You can have jenkinsfiles inside backend and frontend modules and just point to them on each pipeline, eg:
and on the pipeline itself you just cd to the submodule and execute its commands:
pipeline {
agent any
stages {
stage('build') {
steps {
sh 'cd backend'
sh 'mvn clean package'
}
}
//other stages
}
}
if you don't want to cd to a sub module you can use sparse checkouts but in this case you have to change the path to the jenkinsfile accordingly because it will be on the root folder.

Run gradle commands from other directory

I have folder "A" and folder "B"
Folder "B" is having gradle code
I want to run gradle clean and gradle build command from folder "A" of folder "B"
How do I do this?
You should use the "start directory" parameter (-p, --project-dir : see Environment options)
I think the other available parameter -b --build-file could work as well, but its main usage is when your build script filename differs from default build.gradle.
Use the -b parameter(i.e. --build-file)
cd A
gradle -b ../B/build.gradle
for me this works
gradle clean build --console=plain -p ${projectPath}
Where:
clean: Is to "clean" build/libs folder.
Console plain: To show only build results in console
// Compilando
sh(label: 'Compilando', script: "gradle clean build --console=plain -p ${rutaTemp}")
sh(label: 'Listando archivos', script: "ls -lart ${rutaTemp}")
This is harder than it looks.
Dispite setting different values for --project-dir , --gradle-user-home , --build-file
No matter what you do, when you "println project.projectDir" from your build.gradle
script it will ALWAYS report back the directory in which "build.gradle" lives.
I wanted to re-arrange things in gradle because gradle pollutes your root directory
with a lot of junk! Uncle Bob of "Clean Code" (Robert C. Martin) would probably refer to this behavior as "rude code".
I finally figured it out after searching around all day.
Here is my project structure:
<root_folder>
|
+--[ .git ]
+--[ .gitignore ]
|
+--[-]src/main/java
| |
| +--Main.java
|
+--[-]RUN_ON_CMD
|
+--[-]Gradle
+--[ build.gradle ]
+--[ RUN.sh ]
|
+--[-]GENERATED
.gitignore :
GENERATED/
build.gradle :
apply plugin: 'java'
apply plugin: 'application'
println "[project.projectDir]:"
println project.projectDir
mainClassName = 'Main'
sourceSets {
main {
java {
//:Because "build.gradle" lives in:
//:<root>\RUN_ON_CMD\Gradle\GENERATED\
srcDir '../../../src/main/java'
}
}
}
RUN.sh
build_gradle=$( realpath build.gradle )
echo $build_gradle
current_directory=$( realpath "." )
echo $current_directory
generated=${current_directory}/"GENERATED"
echo $generated
cp $build_gradle $generated/"build.gradle"
gradle run -b $generated/"build.gradle" -g $generated --no-daemon
main.java
public class
Main{
public static void
main(
String[] args
){
System.out.println("[MAIN]");
}
}
To Run:
Do a "git bash here" inside the "Gradle" folder.
Then type:
./RUN.sh
And hit ENTER
My output: (TDD_JAVA == root_folder )
JMIM#DESKTOP-JUDCNDL MINGW64 /c/DEV/REPO/GIT/TDD_JAVA/RUN_ON_CMD/Gradle (master)
$ ./RUN.sh
/c/DEV/REPO/GIT/TDD_JAVA/RUN_ON_CMD/Gradle/build.gradle
/c/DEV/REPO/GIT/TDD_JAVA
/c/DEV/REPO/GIT/TDD_JAVA/RUN_ON_CMD/Gradle
/c/DEV/REPO/GIT/TDD_JAVA/RUN_ON_CMD/Gradle/GENERATED
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/5.4.1/userguide/gradle_daemon.html.
Daemon will be stopped at the end of the build stopping after processing
> Configure project :
[project.projectDir]:
C:\DEV\REPO\GIT\TDD_JAVA\RUN_ON_CMD\Gradle\GENERATED
> Task :run
[MAIN]
BUILD SUCCESSFUL in 8s
2 actionable tasks: 1 executed, 1 up-to-date
All the junk generated by gradle is put into
the "GENERATED" folder. Then my .gitignore makes sure not to commit any of that junk.

Can not find class define, when I build a Spring Boot application with Maven by Jenkins and execute JAR file?

I suppose it can not find the class path. Because I can run the jar file JAR in a local environment of the IDE (IntelliJ IDEA). I use the code snippets below to print class path information.
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
if (urls == null || urls.length == 0) {
System.out.println("Is this a empty classpath?");
}
for(URL url: urls){
System.out.println("This is classpath:" + url.getFile());
}
When I click the Run button in IntelliJ IDEA, it can list all dependency class, such as, It's right.
This is classpath:/Users/admin/.m2/repository/org/springframework/boot/spring-boot-starter/1.5.10.RELEASE/spring-boot-starter-1.5.10.RELEASE.jar
This is classpath:/Users/admin/.m2/repository/org/springframework/boot/spring-boot/1.5.10.RELEASE/spring-boot-1.5.10.RELEASE.jar
But when I run it locally, it just prints one message. It's just my JAR package directory. It's wrong.
I read the documentation about the manifest file. It does contain a JAR file. Its location is main/resources directory. But it has no directory prefix. It's generated by IntelliJ IDEA automatically. And I unzip the JAR package to check the META-INF/MANIFEST.MF file. It also contains the Main-Class key.
Manifest-Version: 1.0
Class-Path: spring-data-rest-core-2.6.10.RELEASE.jar mapstruct-1.1.0.F
inal.jar logback-core-1.1.11.jar javax.transaction-api-1.2.jar
I check my pom.xml file. It has the maven-jar-plugin configuration. I comment out classpathPrefix and classpathLayoutType. I consider it seems like no use.
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!--<classpathPrefix>lib/</classpathPrefix>-->
<mainClass>com.hzlf.LetFunGoApplication</mainClass>
<!--<classpathPrefix>/Users/admin/.m2/repository</classpathPrefix>-->
<!--<classpathLayoutType>repository</classpathLayoutType>-->
</manifest>
</archive>
</configuration>
</plugin>
I doubt it is a wrong configuration for this maven-jar-plugin. Its classPathPrefix is a relative path. How can I write it correctly about repository? My local Maven home directory is /Users/admin/.m2/. In my Docker container, it's /root/.m2.
I use a Jenkinsfile to pull an image from Docker hub in my project. Here is my
Jenkinsfile configuration. In the deliver.sh file, just to run the JAR package.
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v $HOME/.m2:/root/.m2'
}
}
stages {
stage('build') {
steps {
sh 'mvn --version'
sh 'mvn clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('Deliver') {
steps {
sh './jenkins/scripts/deliver.sh'
}
}
}
}
This is error information. It confused me a long time.
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/autoconfigure/web/HttpMessageConverters
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.autoconfigure.web.HttpMessageConverters
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
$ docker stop --time=1 693b10dd721c5780761b00eef880b793f6fa2e94afb77e9ffbac9474360f8a5f
$ docker rm -f 693b10dd721c5780761b00eef880b793f6fa2e94afb77e9ffbac9474360f8a5f
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE
1: https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
[2]: https://i.stack.imgur.com/CaMnb.png
[3]: https://i.stack.imgur.com/kbVvJ.png
I resolve it by modifying my deliver.sh. I don't know the real reason, but it works. I just delete Test stage and Deliver stage. I guess it results from the 'post' option in deliver.sh.
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v $HOME/.m2:/root/.m2'
}
}
stages {
stage('build') {
steps {
sh 'mvn --version'
sh 'mvn clean package'
}
}
}
}

How to build Hello-World project with maven structure?

I am new with java and start to reading maven but the document is not clear for me. I have a simple Hello-World project like so :
package main;
public class Hello
{
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
I want to implement this in maven structure .What should I do for this ?
I download and install appache-maven-3.3.3-bin.zip and set the environment variable .
See this page.
Using this command:
mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=com.mycompany.app \
-DartifactId=my-app
It will generate a new directory my-app that is a complete Maven project with the recommended layout, that is:
$ find my-app/
my-app/
my-app//pom.xml
my-app//src
my-app//src/main
my-app//src/main/java
my-app//src/main/java/com
my-app//src/main/java/com/mycompany
my-app//src/main/java/com/mycompany/app
my-app//src/main/java/com/mycompany/app/App.java
my-app//src/test
my-app//src/test/java
my-app//src/test/java/com
my-app//src/test/java/com/mycompany
my-app//src/test/java/com/mycompany/app
my-app//src/test/java/com/mycompany/app/AppTest.java
Customize the groupId and artifactId according to your needs.
See Introduction to the Standard Directory Layout for more details about the layout.

Categories