Check for unresolved properties in Maven Resources - maven

Given the following property in src/main/resources/hello.xml
<test>${resolved.property}</test>
<test>${unresolved.property}</test>
With properties:
resolved.property=test
How do I validate, after going through mvn:resources filtering, if there are any unresolved properties left?

You can use the XML Maven Plugin to validate your XML file after resource filtering has completed.
This plugin can validate XML files against a schema or even just check that they are well formed (which will be sufficient to verify that your XML files do not contain property tokens).
You declare the plugin like so:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
<configuration>
<validationSets>
<validationSet>
<dir>... your xml dir ...</dir>
<includes>
<include>*.xml</include>
</includes>
</validationSet>
</validationSets>
</configuration>
</plugin>
Note: the use of <phase>process-resources</phase> is important here since you want to ensure that validation runs after your resources have been filtered.

Related

swagger maven plgin executions do not run independant

I use the latest swagger-maven-plugin from the io.swagger.core.v3 to generate my static swagger api documentation.
In my project, I have to separate apis so I want to get a json and yml representation for each api within one package process.
<plugin>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>2.2.6</version>
<configuration>
<outputPath>${basedir}/target/</outputPath>
<outputFormat>JSONANDYAML</outputFormat>
<prettyPrint>true</prettyPrint>
</configuration>
<executions>
<execution>
<id>1</id>
<goals>
<goal>resolve</goal>
</goals>
<configuration>
<resourcePackages>
<resourcePackage>de.test.rest</resourcePackage>
</resourcePackages>
<outputFileName>swagger</outputFileName>
<configurationFilePath>${basedir}/src/main/resources/openApiConfig.yml</configurationFilePath>
</configuration>
</execution>
<execution>
<id>2</id>
<goals>
<goal>resolve</goal>
</goals>
<configuration>
<resourcePackages>
<resourcePackage>de.test.secondAPI</resourcePackage>
</resourcePackages>
<outputFileName>secondAPI</outputFileName>
<configurationFilePath>${basedir}/src/main/resources/secondOpenApiConfig.yml</configurationFilePath>
</configuration>
</execution>
</executions>
</plugin>
PROBLEM:
the execution creates the expected json and yml files for each execution
swagger.yml
swagger.json
secondAPI.yml
secondAPI.json
The problem is, that the seconAPI files are a copy of the swagger files.
I've read the documentation and I thought that configuration in the plugin root is shared between multiple executions. Configurations within the execution tag are individually used per execution.
Is there a way to run the executions in parallel with individual configuration?
Or is it a problem with the plugin itself?
EDIT:
Each execution works as expected when there is only one execution defined in the executions tag.

IOException thrown when processing xsd dependencies in maven

I have a problem while processing .xsd file during my maven build.
I use jaxb2 plugin but I have to download external dependiencies from my .xsd files. The problem is that these dependencies (.xsd) are from enviroment which is unstable and very often my build fails because maven cannot download xsd file. How to configure jaxb plugin to force him to try download xsd few times to prevent build failure?
Part of my pom.xml configuration:
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<configuration>
<strict>false</strict>
<extension>true</extension>
<args>
<arg>-Xfluent-api</arg>
<arg>-XtoString</arg>
<arg>-Xsetters</arg>
<arg>-XenumValue</arg>
</args>
<plugins>
<plugin>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>${jaxb.fluentapi.version}</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.9.3</version>
</plugin>
</plugins>
<bindingDirectory>src/main/resources/jaxb</bindingDirectory>
<bindingIncludes>
<include>bindings.xml</include>
</bindingIncludes>
<schemas>
<schema>
<fileset>
<!-- Defaults to schemaDirectory. -->
<directory>${project.basedir}/src/main/resources/orbeons</directory>
<!-- Defaults to schemaIncludes. -->
<includes>
<include>*.xsd</include>
</includes>
</fileset>
</schema>
</schemas>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/generated-sources/orbeons</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Author of the maven-jaxb2-plugin here.
You have two parts here: managing the downloads of external resources and compiling the schemas, rewriting "external" links to local files.
The first (managing downloads) is not in the scope of the maven-jaxb2-plugin, the second is supported with
catalogs.
In short, you can create a catalog file like this:
REWRITE_SYSTEM "http://www.w3.org" "w3c"
Or this:
REWRITE_SYSTEM "http://schemas.opengis.net" "maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc"
And use this file to "rewrite" absolute links to local files or resources within Maven artifacts:
<configuration>
<catalog>src/main/resources/catalog.cat</catalog>
</configuration>
As for the first part, I don't think managing downloads with retries, continuations and all other stuff should be in the scope of the JAXB2 Maven plugin.
ps. You don't need build-helper-maven-plugin/add-source with maven-jaxb2-plugin, source directory is added automatically.
Apparently the maven-jaxb2-plugin does not support such a feature. (And neither does the maven-download-plugin nor even the maven-dependency-plugin).
Three solutions come into my mind at the moment (plus two and a half inspired by LIttle Ancient Forest Kami's comment) [Numbers reflect the precedence of what I would do]:
Use a CI tool (Jenkins, etc.) that supports retry on job failure. [1]
Handmade:
Use the GMavenPlus plugin with a script ... [2]
Use the Maven AntRun plugin with a script ... [3]
Use the Exec Maven plugin with a program ... [5]
... that performs the download and retry and bind it to the generate-resources phase in your project's POM.
Create a Maven plugin with appropriate parameters (url, outputDirectory, retryCount) that uses the maven-download-plugin and performs the retry. Bind its goal to the generate-resources phase in your project's POM. [4]
Create a check-download Maven project that uses the maven-download-plugin bound to the generate-resources phase to download the .xsd. [6]
Create a shell script that contains the following (in pseudo code):
download:
counter++
<check-download project>/mvn generate-resources
if error and counter < maxRetryCount goto download
if not error
<your project>/mvn ...
else
display appropriate error message
There is also a question Maven download retry? from 2005. Unanswered.

Configuring Javadoc aggregation in Maven

I'm trying to create an aggregate Javadoc site for all the modules in my project, but I can't seem to configure the plugin in a way that is satisfactory. Mainly, I can't seem to get it to aggregate the javadocs all the while detecting links and excluding certain packages. Essentially, it appears the configuration of the plugin is ignored entirely.
I have a root pom.xml that refers to a bunch of submodules and contains the following configuration:
<modules>
<module>foo</module>
<module>bar</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.maven.apache.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>aggregate</id>
<phase>site</phase>
<goals>
<goal>aggregate</goal>
</goals>
<configuration>
<links>
<link>http://docs.oracle.com/javase/6/docs/api</link>
<link>http://static.netty.io/3.5/api</link>
<link>http://google-guice.googlecode.com/git/javadoc</link>
<link>http://docs.guava-libraries.googlecode.com/git-history/release/javadoc</link>
<link>http://fasterxml.github.com/jackson-databind/javadoc/2.0.4</link>
<link>https://developers.google.com/protocol-buffers/docs/reference/java</link>
</links>
<bootclasspath>${sun.boot.class.path}</bootclasspath>
<additionalJOption>-J-Xmx1024m</additionalJOption>
<detectJavaApiLink>true</detectJavaApiLink>
<detectLinks>true</detectLinks>
<excludePackageNames>*.testing.*</excludePackageNames>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
But when I run mvn javadoc:aggregate with this setup, I end up with a javadoc site that has no links to any of the referenced libraries and still includes all the testing classes.
I don't even see the plugin attempting to download the package-list for each declared link source.
On the other hand, generating the javadoc for each individual module works well and as expected.
What am I getting wrong?
Plugin configurations can be placed on two levels; inside the execution tag or outside of it ("global").
When the configuration is inside the execution tag it belongs to that particular execution. In your case you will have to run mvn site for it to execute since it is bound to that phase.
When the mvn javadoc:aggregate command is used it looks for the "global" configuration. In your pom there is no such configuration and thus it uses the default configuration.
Change your plugin configuration to this instead:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<configuration>
<links>
<link>http://docs.oracle.com/javase/7/docs/api</link>
<link>http://static.netty.io/3.5/api</link>
<link>http://google-guice.googlecode.com/git/javadoc</link>
<link>http://docs.guava-libraries.googlecode.com/git-history/release/javadoc</link>
<link>http://fasterxml.github.com/jackson-databind/javadoc/2.0.4</link>
<link>https://developers.google.com/protocol-buffers/docs/reference/java</link>
</links>
<bootclasspath>${sun.boot.class.path}</bootclasspath>
<additionalJOption>-J-Xmx1024m</additionalJOption>
<detectJavaApiLink>true</detectJavaApiLink>
<detectLinks>true</detectLinks>
<excludePackageNames>*.testing.*</excludePackageNames>
</configuration>
<executions>
<execution>
<id>aggregate</id>
<phase>site</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
You can place a configuration inside the execution part to override and specialize the configuration for that execution.
BTW The <groupId> is wrong in your pom. It should be
<groupId>org.apache.maven.plugins</groupId>
and not
<groupId>org.maven.apache.plugins</groupId>

How to exclude files from being copied, by maven, into the exploded war

I have a Java web app, in which I have some folders within the standard webapp source directory (src/main/webapp) that I don't want to get copied over into the war (exploded or packaged).
One of the reasons I don't want these files copying over is that we run the YUI JS & CSS minimizer & compressor on .js and .css files within the exploded war. The files that I want to exclude produce errors during the compression phase. The other reason I don't want them adding to the war is that they support testing a single page JS app that lives within the webapp (they are client side JS test scripts that rely on node / angular.js).
Below are the relevant sections from the POM.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>parent-resources</id>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<overlays>
</overlays>
<webappDirectory>${project.build.directory}/${project.build.finalName}-work</webappDirectory>
</configuration>
<phase>generate-sources</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
I have tried, unsuccessfully, to use warSourceExcludes to exclude certain paths, but to no avail. An example of my usage is shown below, where client/ is a folder directly beneath src/main/webapp:
<configuration>
...
<warSourceExcludes>
<excludes>
<exclude>
client/
</exclude>
</excludes>
</warSourceExcludes>
...
</configuration>
What is the correct way to exclude certain paths, and or individual files, within the web app source directory from being included in the exploded war?
UPDATE
Following on from the suggestion from #maba I updated the configuration as follows:
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<overlays>
</overlays>
<webappDirectory>${project.build.directory}/${project.build.finalName}-work</webappDirectory>
<warSourceExcludes>client/</warSourceExcludes>
</configuration>
The folder, client/, still is getting copied across. Any ideas?
Thanks to #alexksandr & #maba for their answers - which though correct didn't fully resolve my issue.
The solution seems to be - though I am not sure exactly why this is the case - that the configuration section is not picked up on when it is placed within the execution section.
Taking my original pom.xml and re-factoring it to make it work gives:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<overlays>
</overlays>
<webappDirectory>${project.build.directory}/${project.build.finalName}-work</webappDirectory>
<warSourceExcludes>client/</warSourceExcludes>
</configuration>
<executions>
<execution>
<id>parent-resources</id>
<phase>generate-sources</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
The important detail seems to be that the configuration should be at the top level of the plugin and not within the execution section - though clearly the xml in my first attempt to use warSourceExcludes was way off target (see original question prior to the update section).
I could find no configuration of <warSourceExcludes> which worked, however <packagingExcludes> did work:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
<configuration>
<packagingExcludes>excludeMe/**</packagingExcludes>
</configuration>
</plugin>
In order to exclude all files from folder use wildcards like that client/**
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<overlays>
</overlays>
<webappDirectory>${project.build.directory}/${project.build.finalName}-work</webappDirectory>
<warSourceExcludes>client/**</warSourceExcludes>
</configuration>
Your warSourceExcludes is wrong. Here is what the maven-war-plugin says regarding warSourceExludes:
The comma separated list of tokens to exclude when copying the content of the warSourceDirectory.
So in your case this is what your configuration should look like:
<configuration>
...
<warSourceExcludes>client/</warSourceExcludes>
...
</configuration>
This means also that if you want to add some more excludes, just add them separated with a comma:
<configuration>
...
<warSourceExcludes>client/,otherDir/,evenMoreDir/</warSourceExcludes>
...
</configuration>

get maven to replace values based on user/build.properties

im at the point in my project where im moving data connections to the beta and production databases for testing. obviously, having the alpha database credentials stored in the source repository is fine, but the beta and production credentials, id be put in front of a firing squad for that one.
i know maven can have a {userdir}/build.properties file. this is the file i want to use to keep the db credentials out of the source repository. but i can't seem to get maven to figure out that for file x.cfg.xml it has to replace values.
so i have in one of my hibernate.cfg.xml files this line
<property name="hibernate.connection.url">#ssoBetaUrl#</property>
now how do i get maven to replace that variable with the value thats in the {userdir}/build.properties file?
edit-------------
ive been playing with the properties-maven-plugin plugin but i seem to not be able to get it to fire. i put this in my parent pom
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<id>read-properties</id>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
</execution>
</executions>
</plugin>
but when it builds, it does not fire. if im reading http://maven.apache.org/maven-1.x/reference/properties.html right it should find the build properties file in the ~/build.properties folder and go from there, but im not sure.
I think you are approaching this the wrong way around. Instead of having the build process bake the appropriate connection details into the JAR file you should instead have the program look for a configuration file at startup.
Typically, my hibernate based apps, will look for a file under %user.home&/.appname/config.properties and load DB credentials and other deployment specfic data from there. If the file is missing, a default version can be included in the JAR and copied to this location (on initial startup so you don't have to copy-paste the file to new systems) that is then edited with appropriate settings.
This way, you can use the same build to produce JAR (or WAR) files for test and production servers, the differences will be in the (presumably already deployed) configuration files. This also makes it possible to have multiple production deployments, each talking to a different database, without any complications in the build process.
You could use two plugins.
properties-maven-plugin
replacer
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>{userdir}/build.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>target/**/*.*</include>
</includes>
<replacements>
<replacement>
<token>#ssoBetaUrl#</token>
<value>http://[anyURL]</value>
</replacement>
</replacements>
</configuration>
</plugin>

Resources