maven-war-plugin ignores user property war.warName - java

If I add the following property in my POM, the maven-war-plugin uses it correctly:
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
However if I add the following property the plugin ignores it (the generated WAR has the default name, i.e. artifactId-version):
<properties>
<war.warName>${project.artifactId}</war.warName>
</properties>
Here are two excerpts from the maven-war-plugin documentation:
warName:
The name of the generated WAR.
Type: java.lang.String
Required: Yes
User Property: war.warName
Default: ${project.build.finalName}
failOnMissingWebXml:
Whether or not to fail the build if the web.xml file is missing. Set to false if you want you WAR built without a web.xml file. This may be useful if you are building an overlay that has no web.xml file.
Type: boolean
Since: 2.1-alpha-2
Required: No
User Property: failOnMissingWebXml
Default: true
(Source: https://maven.apache.org/plugins/maven-war-plugin/war-mojo.html)
Why is the behavior different between failOnMissingWebXml and war.warName?
Also, if other plugins can use the value ${project.build.sourceEncoding} why can't maven-war-plugin use the value of ${project.build.finalName}?
<properties>
<!-- plugins use these values correctly -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<!-- not "found" by maven-war-plugin -->
<war.warName>${project.artifactId}</war.warName>
<project.build.finalName>${project.artifactId}</project.build.finalName>
</properties>
Thanks a lot! :)
EDIT: Since the version 2.4 of maven-war-plugin war.warName works as expected, however I still don't understand why setting project.build.finalName doesn't work.

The problem is simply that you mistaken property cause user property is meant to be used usually from command like this:
mvn -Dwar.warName=xxx war:war
If you like to use it in a pom file you have to use it like this:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>WhatEverYouLike</warName>
</configuration>
</plugin>
...
</plugins>
</build>
...
And you shouldn't use properties in your pom to define such things. Better use the configuration tag for this.
The ${project.build.finalName} should be used like this:
<project..>
<build>
<finalName>WhatYouLIke</finalName>
..
</build>
</project>
The structure can be seen if you look into the maven model.
The usage of ${project.build.sourceEncoding} is simply a convention in Maven plugins so you could define that property which is picked up by a larger number of plugins to be used for source encoding (I have to admit this is a little bit misleading). The original idea behind was having something in the maven model to represent the encoding which would mean to change it which is not really possible at the moment.

Related

Maven plugin CLI parameter overwriting <configuration> in pom.xml

How does/should Maven plugins behave with regards to the order in which they process configuration options? I would expect that properties passed via CLI overwrite those defined in a <configuration> block in pom.xml.
Here's an example.
pom.xml
<plugin>
<groupId>group</groupId>
<artifactId>artifact</artifactId>
<version>1.2.3</version>
<executions>
...
</executions>
<configuration>
<url>foo.com</url>
</configuration>
</plugin>
CLI
mvn group:artifact:1.2.3:doit -Dmymojo.url=bar.com
I am currently debugging a plugin (not mine) that gives precedence to the url value defined in the POM rather than the one passed on the CLI. Is that how mojos are supposed to behave i.e. a Maven feature rather than a plugin bug? I didn't find anything mentioned in the ref guide.
As per https://issues.apache.org/jira/browse/MNG-4979 this works as designed. I find it counter-intuitive and don't find the reasons given in MNG-4979 convincing.
If your setup allows to modify the pom.xml you can work around this behavior as suggested by JF Meier (and the issue above).
<properties>
<mymojo.url>foo.bar</mymojo.url>
</properties>
<plugin>
<groupId>group</groupId>
<artifactId>artifact</artifactId>
<version>1.2.3</version>
<executions>
...
</executions>
<configuration>
<url>${mymojo.url}</url>
</configuration>
</plugin>
Through the command line, you set a property url. This would override an entry <url>foo.com</url> in the <properties> section of the POM.
Many plugins allow to set configuration entries through properties, but these properties do not automatically have the same name. In the documentation, this is usually called user property. To see examples, look e.g. at
https://maven.apache.org/plugins/maven-dependency-plugin/get-mojo.html

project-to-test pom configuration doesn't seem to take effect

I'm new to Java scene and was attempting to create a maven plugin.
I started with the archetype 'maven-archetype-plugin' and it comes with a default testing scaffold with artifact id 'maven-plugin-testing-harness'.
One confusing thing I've observed is that in the pom of testing directory 'project-to-test' exists a configuration over output directory
<build>
<plugins>
<plugin>
<artifactId>my-plugin-artifact-id</artifactId>
<configuration>
<!-- Specify the MyMojo parameter -->
<outputDirectory>target/test-harness/project-to-test</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
This parameter configuration didn't seem to take effect at all. The actually output path was set to default ('./target/) regardless
What did I do wrong?
After running maven commands in the project-to-test directory, I've realized that the newly created plugin was resolved to package org.apache, which is completely wrong.
With this hint I've added label to the pom build section and it now behave as expected.

Using #project.version# with Liquibase in a multimodule Maven project

It was a little bit hard to come up with a meaningful title, hope it will become clear enough after the explanation. I have searched through a number of Qs and As on SO, and they were all very close to the problem I am experiencing, but still not close enough.
In general, what I want to accomplish is to store project version in DB by accessing the maven property #project.version# from a .csv file which is loaded by a Liquibase script.
My maven project structure looks like this:
parentModule
pom.xml
|
---moduleA
|__pom.xml
---moduleB
|__pom.xml
---moduleC
|__pom.xml
...
Pom.xml are defined as:
**PARENT POM**
<project ...>
<groupId>com.parent</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>parent</name>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.2.1.RELEASE</version>
<relativePath />
</parent>
<properties>
<java.version>8</java.version>
</properties>
<modules>
<module>moduleA</module>
<module>moduleB</module>
<module>moduleC</module>
...
</modules>
<build>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
----------------------------------------------------------------------
**CHILD POM**
<project ...>
<artifactId>moduleC</artifactId>
<name>moduleC</name>
<parent>
<groupId>com.parent</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<dependency>
...
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>moduleC/src/main/resources/db/changelog/</directory>
<filtering>true</filtering>
<includes>
<include>**/app_version.csv/</include>
</includes>
</resource>
</resources>
</build>
</project>
Liquibase scripts are defined in moduleC/src/main/resources/db/changelog/changelog-master.xml etc., while the .csv files with initial values are located in moduleC/src/main/resources/db/users.csv etc. In one of those csv files, I want to push #project.version# value, like this:
id;app_key;app_value;created_by;last_modified_by
1;app-version;#project.version#;system;system
Since that file is located in moduleC, I used maven resource filtering even inparentModule <build/> to filter that file so it can resolve #project.version# property, but with no luck:
<build>
<resources>
<resource>
<directory>moduleC/src/main/resources/db/changelog/</directory>
<filtering>true</filtering>
<includes>
<include>**/app_version.csv/</include>
</includes>
</resource>
</resources>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
There are errors, one that says that master changelog cannot be found, while in other cases just string value #project.version# is stored. Seems to me I should include app_version.csv and its location (moduleC) as resource inside <build> tag withing parentModule pom.xml, but every combination of referencing it fails. Is there a solution to reference it properly (either from parentModule or moduleC pom.xml) or there might be an easier way to store #project.version# with liquibase?
I am extremely sorry for not replying on time, was temporarily removed from the project after posting the question and was not able to access the git repository due to change of location. So far, I have tried all of the proposed actions, but with no result. In the end, what I found to work was an accepted answer posted here. I have added the build block inside mavenC module pom.xml and it worked. Nevertheless, thank you all immensely for posting and helping.
I think you need to use the maven-replacer-plugin in your build cycle. It will be configured to process the 'app_version.csv' file and output the substituted file content to the 'target/classes' folder. The subsequent packaging phase will ensure the csv file with the current pom version will be bundled into the artifact that the liquidbase tool then handles.
Looks like you're using the wrong syntax for filtering in the CSV-file. Instead of using #project.version#, try ${project.version} instead:
Check the <directory>moduleC/src/main/resources/...</directory>, if the resources plugin lives in the child POM of moduleC then there is no need for the prefix.
Try replacing with <directory>src/main/resources/..</directory>
Resources filtering of a module should be in the build of the module itself.
The project.version property will be inherited from the parent.
Be careful so the filtering does not mess with your xml files.
I think the syntax should be ${project.version}
Can you share your liquibase maven plugin configuration ?
The markup should point to your master changelog.
Here is two other solutions:
Another solution would be to create a liquibase changeset every time you create a new version. You can do it programmatically using liquibase java SDK in a spring component which run on startup of your project or create the changeset yourself.
Another solution would be to use Spring Boot Actuator to retrieve project version.
For this you need to add <goal>build-info</goal> in the goals of spring-boot-maven-plugin

Maven PMD plug-in not generating a report with 'mvn site' command or 'pmd:pmd'

I am reading an interesting tutorial here: http://www.avajava.com/tutorials/lessons/how-do-i-generate-pmd-and-cpd-reports-for-a-site.html?page=1
This tutorial shows how to use Maven to run the open-source static-analysis tool, PMD, and to see the generated output on a Maven created website. Maven can easily create websites with mvn site command, but this tutorial shows how to use PMD for more helpful metrics on the source code.
The instructions were followed to the best of my ability. Here is my pom.xml file that came from reading the tutorial:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.name.bookstore</groupId>
<artifactId>bookstore</artifactId>
<packaging>jar</packaging>
<version>1</version>
<name>bookstore</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<!-- start for deploying using webdav -->
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-webdav</artifactId>
<version>1.0-beta-2</version>
</extension>
</extensions>
</build>
<distributionManagement>
<!-- start -location where site is deployed -->
<site>
<id>site.deployments</id>
<name>Site deployments</name>
<url>dav:localhost/${basedir}</url>
</site>
</distributionManagement>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>
</plugin>
</plugins>
</reporting>
</project>
When I run the command: mvn clean site I get a website built by Maven with a bunch of different pages but none of them show anything in regards to PMD. What am I missing here? Why am I not seeing anything in regards to PMD in the generated website?
Also, when I run mvn pmd:pmd there is a successful build but I do not obtain any helpful PMD metrics. I even coded in some unused variables and methods in one of my Java source files as illustrated in the above linked tutorial and there is no helpful output.
The mvn pmd:pmd command does appear to create some files though. A couple are files of rules for the engine it looks like and the others are empty. Please see the screen-shots of this below:
Figure 1: Files created by pmd:pmd command
Figure 2: Empty pmd file - even though there are obvious errors in Java source file
Does anyone out there know what is up? Why is PMD not working with Maven for me?
Thanks for reading this.
Also, from what I have read around the Internet on PMD's website and Maven's website there should be some information in the "Project Reports" section. There is no data here though from PMD. Please see the below screen-shot.
Figure 3: No PMD Data found in Project Reports
Regards
UPDATE
When I change the PMD section of the pom.xml file to the below snippet I obtain some CPD results via PMD but still nothing from PMD on code bugs. I even coded in an NullPointerException and PMD said nothing even when issuing the mvn pmd:check command.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.4</version>
<configuration>
<linkXref>true</linkXref>
<sourceEncoding>utf-8</sourceEncoding>
<minimumTokens>1</minimumTokens>
<targetJdk>1.7</targetJdk>
</configuration>
</plugin>
In the snippet I changed the sourceEncoding tag to be utf-8 because everything I see in regards to this is utf-8. I also changed the minimumTokens value to 1 to try to get more output from this plug-in. I also put this snippet in the <build> section to try and get results but still nothing... :/
Thanks for studying this...
The maven-pmd-plugin by default skips nowadays empty reports (property skipEmptyReport). You'll need to set this to false, to get in your site always a PMD/CPD report:
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.4</version>
<configuration>
<skipEmptyReport>false</skipEmptyReport>
</configuration>
</plugin>
</plugins>
</reporting>
This applies for both PMD and CPD. I assume, this is your problem, as in Figure 2, you show, there are no PMD violations detected (pmd.xml file is empty).
The property minimumTokens configures CPD and defines how long a code snipped at a minimum must be to be declared as a duplicate. The lower the number, the more duplicates are detected, but the duplicates can also be much shorter and therefore maybe more often false positives.
Without further configuring maven-pmd-plugin it uses by default these three PMD rulesets: java-basic, java-imports, java-unusedcode. See also property rulesets. If you want to detect specific problems, then you'll need to enable these rules. See also How to make a ruleset.

Maven Profile exclude/include directories [duplicate]

I want to use a different source directory for a specific maven profile, however, when I try to specify it in the profile definition I get this error:
Unrecognised tag: 'sourceDirectory' (position: START_TAG seen ...<build>\r\n\t\t\t\t<sourceDirectory>... )
The definition in the pom is as follows:
<profile>
<id>development</id>
<build>
<sourceDirectory>${project.build.directory}/new-src</sourceDirectory>
.
.
.
</build>
</profile>
What I am trying to do is to process the source files before its compilation if and only if this profile is active. My process will change the source files on the fly, throw the changed sources in the "new-src" directory and compile that directory as if it was the usual "src/main/java". Everything else in the lifecycle should behave normally. If this approach is flawed, could anyone point me into the right direction?
According to the documentation, you can change only few <build> parameters in the profile and <sourceDirectory> is not one of them.
I'd configure the main <build> to take sources from path defined by some property (eg. src.dir), set this property to src/main/java and override it in the custom profile:
<project>
...
<properties>
<src.dir>src/main/java</src.dir>
</properties>
<build>
<sourceDirectory>${src.dir}</sourceDirectory>
...
</build>
<profiles>
<profile>
<id>development</id>
<properties>
<src.dir>${project.build.directory}/new-src</src.dir>
</properties>
</profile>
</profiles>
</project>
See Maven model, it is not allowed to define a sourceDirectory within a profile. The only thing you can do is specify the sourceDirectory within the plugin configuration, assuming it is available.

Categories