Read liquibase change log properties from external property file with maven - liquibase

I want to read Liquibase change log properties from an external property file. I do not want to define them in the databasechangelog.xml in property tag as I want different parameters for different environments. My external property file will be chosen according to the profile I chose for the maven plugin.
E.g. CREATE OR REPLACE SYNONYM ${schema1}.myTable FOR ${schema2}.myTable;
I want these parameters ${schema1} and ${schema2} to picked from an property file. Is this possible
Edit: According to #bilak comment I tried this
pom.xml:
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<propertyFile>${basedir}/../environments/${build.profile.id}/liquibase.properties</propertyFile>
<changeLogFile>${basedir}/src/main/resources/sql/db-changelog-master.xml</changeLogFile>
</configuration>
</plugin>
liquibase.properties:
driver=oracle.jdbc.OracleDriver<br>
url=xxxxx<br>
username=xxxxxx<br>
password=xxxxxx<br>
parameter.testcolumn=test_column
db config parameters are read correctly but parameter.testcolumn is not used
mvn liquibase:update -Pprofile

You can use file liquibase.properties (default name) and put there variables like:
parameter.schema1=yourSchema1
parameter.schema2=yourSchema2
edit:
That option doesn't work with liquibase-maven-plugin but there could be workaround with maven-exec-plugin:
<profiles>
<profile>
<id>liquibase</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath/>
<argument>liquibase.integration.commandline.Main</argument>
<argument>--defaultsFile=src/main/resources/database/liquibase.properties</argument>
<argument>updateSQL</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
if you execute then mvn exec:exec -Pliquibase it should replace your placeholders with parameters from liquibase.properties.
edit 2019/07 Now you can use property file to load properties from

Related

"No public or protected classes found to document" error from path with accents

My Maven Java 8 project is inside a path which contains accents: C:\Développements\myproject.
When I use maven-javadoc-plugin (event with last 2.10.4 version) I have this error when I try to generate the javadoc of my project (from IntelliJ IDEA 2016.2.4):
[ERROR] javadoc: warning - No source files for package com.mycompany.myproject
[ERROR] javadoc: error - No public or protected classes found to document.
This is strange because I have documented classes in this project.
This error can also occur if you have no public methods in your test classes, which is exactly what can happen because Sonar lint rule S5786 says JUnits should have default package visibility, for readability. Fortunately, you can use the -package javadoc option, to fix this. If you put this in your parent pom:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.version>3.8.1</maven.compiler.version>
<junit.version>5.7.0</junit.version>
</properties>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.9.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<source>8</source>
<additionalOptions>-package</additionalOptions>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</reporting>
<distributionManagement>
<site>
<id>yourid</id>
<url>file:///var/www/html/maven</url>
</site>
</distributionManagement>
then
mvn site-deploy
will give you your default maven site along with the javadoc. Included everything relevant for a Java 8 project.
Had this happen when I created a package-private class with a main method. After marking the class as public the packaging step worked again.
This is not a Maven or plugin problem but purely a Windows problem. Microsoft is too stupid to have a proper encoding set in cmd.exe. You have some stupid DOS encoding. Java's javadoc uses that to read the #options file and fails.
Set _JAVA_OPTIONS=-Dfile.encoding=UTF-8 and you are done. Alternatively, use a Linux distribution or FreeBSD.
The issue remains closed.
Actually this is a referenced bug from maven-javadoc-plugin project: MJAVADOC-333.
So since it is not fixed (it is currently "closed"...) one should just remove the accents from your project path...
Apart from the special character (accent) problem, this may be a problem with your pom.xml:
I had the same problems right now with a project created in Eclipse.
If you create a project in eclipse, it will put java packages/sources directly within the src folder and add the following line to your pom.xml:
<sourceDirectory>src</sourceDirectory>.
If you then decide to move your java files according to the maven conventions and forget to update or remove the sourceDirectory tag, you will end up with exactly the same error:
Your project will build fine, but javadoc will not find it`s sources...

Maven: specify the outputDirectory only for packaging a jar?

How can I specify the outputDirectory only for packaging a jar?
http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html this shows all parameters, but how can I set them in the commandline or pom.xml?
on command line
-DoutputDirectory=<path>
and in pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>/my/path</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
Parameter Expressions
About command line usage:
The parameter documentation specifies that the parameter is initialized to the value of the property ${project.build.directory} (which is the property referring to the target folder)
Here's what this means:
For mojos that are intended to be
executed directly from the CLI, their
parameters usually provide a means to
be configured via system properties
instead of a <configuration/> section
in the POM. The plugin documentation
for those parameters will list an
expression that denotes the system
properties for the configuration. In
the mojo above, the parameter url is
associated with the expression
${query.url}, meaning its value can be
specified by the system property
query.url as shown below:
mvn myquery:query -Dquery.url=http://maven.apache.org
Reference:
Guide to Configuring Plug-ins > Generic Configuration
Configuring ${project.build.directory}
However, ${project.build.directory} is not a system property, it's a property of the Project's Build object.
You can't set maven's internal properties directly on the command line, but you can get there with a little trick by adding placeholders in your pom.xml:
<build>
<directory>${dir}</directory>
</build>
Now, the output directory is set via the property from the command line (using -Ddir=somedirectory). Downside: now you always have to use the -Ddir parameter on the command line.
Using Profiles
But there's help here, too. Just use a profile when you want to configure the directory:
<profiles>
<profile>
<id>conf</id>
<build>
<directory>${dir}</directory>
</build>
</profile>
</profiles>
Now you can either do
# everything goes in someOtherDir instead of target
mvn clean install -Pconf -Ddir=someOtherDir
or plain old
# everything goes in target
mvn clean install
Configuring the Jar Plugin
Now if you just want to change the jar outputDirectory from the command line without redirecting everything from target, we'll modify the profile to configure the plugin from a command line property:
<profiles>
<profile>
<id>conf</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>${dir}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The usage is identical to above:
# everything goes in someOtherDir instead of target
mvn clean install -Pconf -Ddir=someOtherDir
Thanks #Sean Patrick Floyd for the excellent explanation.
Instead of creating a profile and using mvn always by -P switch, I'd like to use another way that making a default value of property ${dir}.
Just define ${dir}'s default value as ${project.build.directory}
<properties>
<dir>${project.build.directory}</dir>
</properties>
and same as #Sean Patrick Floyd, set outputDirectory.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>${dir}</outputDirectory>
</configuration>
</plugin>
</plugins>
Now you can either do
# everything goes in someOtherDir instead of target
mvn clean install -Ddir=someOtherDir
or plain old
# everything goes in target
mvn clean install
If you wish copy dependency jars as well to a target folder, use maven-dependency-plugin.
<project>
...
...
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

When are properties resolved?

I defined a profile at my base-pom which uses a property that is defined by a sub-pom (deploy-location of the appserver-module). The profile shall be used after the initial full-build and thus be inherited to all sub-poms.
The question is: how/when are such properties resolved: when doing the initial full build or when doing a local build of a specific submodule ?
<profile>
<id>quickdeploy</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<outputDirectory>${ear.path}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
${ear.path} is defined in a submodule ...
I just tried out your question a created two artifacts with m2eclipse. The first is q4794952.base which is a simple maven project and has its type set to pom. Then I created the second artifact from (right click on the base project, New => Maven => Maven Module ) which automatically creates the parent tag and the (sub)module inside the base artifact.
When using a module structure like created by the process above (or in genereal where the module is known by the tag) the property from the submodule is know to the "base" and will be resolved in the "full-Build" (as can be seen by using help:effective-pom and the build result of course). If you build just the submodule it's resolved as well because the profile is taken from the parent pom and the property is set in the (sub)module.
Here's my "basepom":
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>q4794952.base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>quickdeploy</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<outputDirectory>${ear.path}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<modules>
<module>q4794952.sub</module>
</modules>
</project>

How to set name of author in a maven project?

packaged maven project contains META-INF/manifest.mf file and in field "Built-by" is login name of current user.
Where or what to set name of author, so maven will use this instead of login name?
This can be overwritten in your pom.xml by adding a manifestEntries section e.g.:
<project ...>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Built-By>${user.name}</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
When invoked from command line, the following will work:
mvn -Duser.name=<username> clean install
In NetBeans 7.4 you can set up the user name globally in the following way:
Tools -> Options -> Java -> Maven, Selecting "Execution" category on the left and setting
Global Execution Options:
-Duser.name=<username>
Alternatively it can be done by setting according property in project-specific build action settings (Project Properties -> Actions -> e.g. Build project).

Configure Maven plugins to stick together

I have parent pom which configures certain plugins
<pluginManagement>
</plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
...
</plugin>
</plugins>
</pluginManagement>
And I have tree of poms which are represent integration tests
A-\
a1
a2
B-\
b1
b2
C-\
D-\
d1
d2
In each a,b,d products I do
<build>
<plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
</plugin>
</plugins>
</build>
The problem is when I will need to add fourth plugin to integration test process for example my custom plugin I will need to move
through all of the integration modules and do manual adding.
You can advice me to remove <pluginManagement> to allow all child just to use them implicitly.
Yes, but in products which are just 'pom' I don't want plugins to do anything: create some resources and put jboss configuration directories.
I wonder is there some kind of
<pluginsBundle>
<groupId>my.group</groupId>
<artifactId>my-integration-test-bundle</artifactId>
<plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
</plugin>
</plugins>
</pluginsBundle>
To allow me use it just like
<plugin>
<groupId>my.group</groupId>
<artifactId>my-integration-test-bundle</artifactId>
<runOnce>true</runOnce>
</plugin>
I would like to add option like
<runOnce>true</runOnce>
to be able to start application server and deploy target only one time per maven launch.
I don't know of a mechanism that does exactly what you need. Your best bet is to define a parent pom with those plugins defined in the build section, rather than the pluginManagement section. In this case the plugin configuration will always be defined. Adding the configuration to a profile in the parent means you can exercise some control over the activation of those plugins.
One refinement to consider is that you can control activation of a profile by the presence or absence of a file. This way you can define the profile in the parent, but have it deactivated in that project because of the marker file being present in the parent. Child projects would not have the marker file in their source, so the profile would be activated for those projects. You can reverse the behaviour by using missing instead of exists if that makes sense for the majority of projects.
<profile>
<id>build</id>
<activation>
<file>
<missing>src/main/resources/build.marker</missing>
<!-- or if you want to enable the profile when the file does exist:
<exists>src/main/resources/build.marker</exists-->
</file>
</activation>
<build>
</plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
...
</plugin>
</plugins>
</build>
</profile>
Alternatively, you could try writing custom plugin with a lifecycle that executes all the required mojos in a forked lifecycle. I recently answered another question with details of how to do this.
Another alternative is to write another plugin that uses Maven shared-io to apply a descriptor
to the pom, that descriptor can define arbitrary configuration that is merged into the pom. Another answer describes how this can be done.
AFAIK, there is no way to declare a bundle of plugins that could be used somewhere else... but there is inheritance.
What about creating a pom with the <plugins> declaration in the <build> section and inheriting from this pom in your integration tests projects? This looks like feasible.