Getting project.build.property from maven in Jenkins - maven

So this problem is vexing me and I decided to ask a question because no answer out there was able to help, the problem is happening SPECIFICALLY to project.build.directory.
I have a Jenkins pipeline, and I need to build this string to deploy my artifact
#${project.build.directory}\${project.artifactId}_${project.version}.car
I am using the following to get some information from the pom.xml
script {
pom = readMavenPom file: 'pom.xml'
deployVersion = pom.properties.'deploy.version'}
So doing both
${deployVersion} and ${pom.version}
works perfectly, so there's no reason for ${pom.build.directory} not to work, but it doesn't. Nevertheless I decided to work around it and expose that property via the pom's properties, since I know the property works inside the pom, so I did, in my pom
<properties>
<build.dir>${project.build.directory}</build.dir>
</properties>
And that don't work either, after assigning pom.properties.'build.dir' to buildDir I get ${project.build.directory} as a literal
#${buildDir}\${pom.artifactId}_${pom.version}.car
I have no idea why this is happening or how to fix. Any ideas?
EDIT: The below was answered in the comments, either escape with another slash (\\) or use a forward slash (didn't test this one though)
Even more weird, the \ disapears and it don't convert pom.artifactId (which will convert properly if I call it without the build directory)

Related

Not able to pass the dynamic value from eclipse to POM

Passing the version to POM.xml.
It shows warning. 'version' contains an expression but should be a constant.
I have to remove this.
I have one Ant project and another maven project. I made one runconfiguration for Ant project where I made one variable with some value suppose 13.2.1
by opting external tool configuration that variable come in list now.now able to pass that variable like -Dversion="${versionjar}".
its working perfactly.
since this versionjar is already set in eclipse. I want to use this while I want to run the maven project by runconfiguration.
want to pass in create manage and runconfiguration like in goal section install -Dversion="${versionjar}" but its not working .
I have to set this variable here also by add button.
How can I pass the variable from eclipse command line like :install -version="${version}"? version is vailable in eclipse variable list while "${version}" is properly send to pom when it is hard coded.
"${version}" is not resolving when send in goals section of run configuration
I'm facing problem when passing the eclipse variable from command line configuration.
in POM
<version>${version}</version>
<packaging>jar</packaging>

maven checkstyle plugin creates an output file and fails checking it

I have a question regarding the maven checkstyle plugin. The problem is that it creates an output file and fails because that file does end with new line (which the plugin is supposed to check for):
[ERROR] target/checkstyle-result.xml:[0] (misc) NewlineAtEndOfFile: File does not end with a newline.
I tried to exclude the target directory from that plugin with:
<properties>
<checkstyle.excludes>**/target/**</checkstyle.excludes>
</properties>
but that does not do anything.
The plugin itself is configured in the parent pom.xml file, so I don't have any control over it.
Any suggestions?
I had the same problem and figured it out. The problems with your rule (and mine before) are the following:
**/target/** does not match the file target/checkstyle-result.xml. A better approach would be **/target/**/*
Since your XML is not source code but a resource, you should use the checkstyle.resourceExcludes property instead.

What is Maven doing with my testclasspath

I'm having issues with a test, which when executed in maven fails to initialize log4j, although a valid log4j.properties is in src/test/resources and therefore should end up on the classpath of the test. But it doesn't, i.e. log4j prints only
log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
log4j:WARN Please initialize the log4j system properly.
In order to debug the problem I printed the classpath from the test itself, using the code here
But instead of a lengthy list of jars and paths I just get
/<projectpath>/target/surefire/surefirebooter6226797341642271676.jar
So my questions are:
WTF is maven doing with the classpath?
Why doesn't my log4j.properties end up on the classpath?
How do I debug this?
Note: In Eclipse I can run the test just fine and everything works as expected.
Another note: the maven project is a multimodule project and I'm only executing a single test from a single submodule, with a commandline like this:
mvn -U -Dtest=de.company.project.SomeTest clean test
Have a good look at the maven-surefire-plugin. By default it creates a jar stuffed with your entire classpath. This is controlled by the useManifestOnlyJar option. This works around the problem of Windows having a classpath limit of 1024 (quoting off the top of my head). Under Linux you wouldn't really feel this pain much as the limit is much higher.
If you are forking the maven-surefire-plugin, it will use a different classpath than the one you're running Maven (and the compilation).
Debugging this kind of crappy situation can be done as follows:
In one of your tests add a loop that lists all the environment variables along with the java system properties.
Debug the tests:
mvn -Dmaven.surefire.debug="-Xdebug \
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=9001 \
-Xnoagent" \
test
I found the answer to question 1.
Maven creates the jar with the weird name on the fly and just puts a MANIFEST.MF file in there. That file contains the classpath, and the main class to be started.
This also answers to some extend question 3.
You can copy that jar file somewhere else, while maven is running, so it does not delete it once it is finished. Then you can examine it as long as you want. Turns out my log4.properties is on the classpath (the target directories for the testclasses is there and the properties files is in that directory ....)
Leaves me with question 2.
It turned out somewhere in the forest of pom.xmls the system property log4j.configuration was set to a rather useless value. Setting that value back to the propervalue as described here solved my immediate problem.
Now I just have to find the broken spot in our poms, but that's a story for a different day.

Quoting and escaping in Maven Exec plugin

How does quoting and escaping work for parameters passed to Maven plugins?
For example I want to pass multiple filenames as arguments to an application run by the Maven Exec plugin:
mvnDebug exec:java -Dexec.mainClass="Main" -Dexec.args="/path/to/file1 /path/to/file2"
But what if the paths have spaces?
I've tried using \":
-Dexec.args="\"/path/to/a file\" /path/to/file2"
and "":
-Dexec.args="""/path/to/a file"" /path/to/file2"
neither works :-(. Neither does moving the first quote before -D.
The source code for the Maven Exec plugin doesn't help me either, it receives a String[] from somewhere, but where?
Note that I must get this to work from the command line, without changes to the POM file.
You could try single quotes (') but I doubt that will work, either.
The problem is that you can have several argument elements inside the POM (hence the array in the plugin's source) but you have only a single property from the command line.
Options:
Patch the plugin and/or open a feature request to support several arguments (maybe exec.args.0, exec.args.1, exec.args.2, ...)
Create a module which depends on this project/module and where you can change the POM
Use an Ant or BASH script. I often use this approach to collect useful commands which aren't easily supported by Maven. mvn dependency:build-classpath -Dmdep.outputFile=... will give you the classpath in this case.

maven with cuke4duke: optionally defining cucumber tags on cmd line

As a test developer using cuke4duke with maven2, I want to be able to optionally select tests by tags on the cmd line. It seems that since maven doesn't have conditionals, the 'optionally' part requires a hack.
The cucumber arg might be e.g. "--tags #firstTag". One way to implement this is to have in pom.xml
<cucumberArgs>
...
<cucumberArg>${tagargs}</cucumberArg>
</cucumberArgs>
Then the cmd line has
mvn integration-test -Dtagargs="--tags #firstTag"
This works fine when I want to define tags, but when I don't include that -D argument (i.e. not selecting by tags), I get
[INFO] No such file or directory - null (Errno::ENOENT)
A workaround is to define ${tagargs} in properties as a duplicate of a cucumber arg I already use:
<properties>
<tagargs>--strict</tagargs>
</properties>
So, worst case is I get "--strict --strict". Is such a hack the best maven is capable of?
I've managed to work around this problem using an ignored negative tag. Note I'm using cuke4duke 0.4.4.
Define a default value for your property that runs all scenarios that are NOT tagged with "ignore" (call it whatever you like).
<properties>
<tagargs>--tags=~#ignore</tagargs>
</properties>
Maven will use this property when you do not pass in a specific value on the command line. Therefore all of your scenarios will match and execute.

Resources