Posts tagged: maven
Consult https://github.com/bigpuritz/javaforge-blog/tree/master/liquibase-sample for the sample project sources.
Quote:
Liquibase is an open source (Apache 2.0 Licensed), database-independent library for tracking, managing and applying database changes.
It is built on a simple premise: All database changes are stored in a human readable yet trackable form and checked into source control.
This post is a simple tutorial demonstrating how to use Liquibase in a real world project. We’ll assume that our sample project lives through multiple phases, each of which adds diverse changes to the database.
Let’s prepare our sample project to use Liquibase within Maven build first. We need to define the liquibase-maven-plugin within the <plugins>…</plugins> block and point it to the liquibase.properties file, containing all properties required by the Liquibase at runtime. Both are demonstrated below.
Often it is required to put some custom resources (e.g. XSDs, WSDLs etc.) under dependency management control.
As soon as Maven is a de facto standard dependency management mechanism in the Java world, this post demonstrates how to use it to manage untypical custom resources as dependencies within the pom.xml.
Let’s assume we have some xsd file (test.xsd in this example), that we want to use as dependency in our POM.
First, we’ll deploy it to the local repository (alternatively you can deploy it to your company’s internal maven repository):
mvn install:install-file -Dfile=test.xsd -DgroupId=com.mycompany.app \ -DartifactId=app-xsd -Dversion=1.0.0 -Dtype=xsd -Dpackaging=xsd
After installation you’ll find the xsd in your local maven repository within the following folder structure:
Next referencing this file as a dependency in your POM is quite simple. Just write:
<dependency> <groupId>com.mycompany.app</groupId> <artifactId>app-xsd</artifactId> <version>1.0.0</version> <type>xsd</type> </dependency>
Furthermore if you want to add this file as a resource to the final artifact generated by Maven, you have to configure maven-dependency-plugin in your POM like this:
<build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.5.1</version> <executions> <execution> <id>copy-dependencies</id> <phase>generate-resources</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/${project.build.finalName}/META-INF</outputDirectory> <includeArtifactIds>app-xsd</includeArtifactIds> <includeTypes>xsd</includeTypes> </configuration> </execution> </executions> </plugin> ... </plugins> </build>
After executing the maven build the app-xsd-1.0.0.xsd file will land in the artifact’s META-INF folder.
In the current project one of my tasks was to simplify the maven release process. This should be a simple one click solution, that satisfies following requirements:
I decided to write a simple Ant script that internally makes use of Maven Ant Tasks.
First a target asking user for all required release informations was born:
<?xml version="1.0" encoding="UTF-8"?> <project name="myprj" default="release" xmlns:artifact="antlib:org.apache.maven.artifact.ant"> <property environment="env" /> <path id="maven-ant-tasks.classpath" path="maven-ant-tasks-2.1.3.jar" /> <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="antlib:org.apache.maven.artifact.ant" classpathref="maven-ant-tasks.classpath" /> <!-- - - - - - - - - - - - - - - - - - target: prerequisites - - - - - - - - - - - - - - - - - --> <target name="prerequisites"> <fail unless="env.MAVEN_HOME" message="Environment variable MAVEN_HOME was not found on your system!" /> </target> <!-- - - - - - - - - - - - - - - - - - target: input - - - - - - - - - - - - - - - - - --> <target name="input"> <artifact:pom id="local.pom" file="pom.xml" /> <script language="javascript"> <![CDATA[ var before = project.getProperty("local.pom.version"); project.setProperty("tmp.release.version", before.replaceAll("-SNAPSHOT", "")); var tmpVersion = project.getProperty("tmp.release.version"); var nextVersionNo = tmpVersion.substr( tmpVersion.lastIndexOf(".") + 1 ); project.setProperty("tmp.next.version", tmpVersion.substr(0, tmpVersion.lastIndexOf(".") + 1) + (parseInt(nextVersionNo)+1) + "-SNAPSHOT" ); ]]> </script> <input message="Please enter the project release version?" defaultvalue="${tmp.release.version}" addproperty="prj.release.version" /> <input message="Please enter the svn tag name?" defaultvalue="${local.pom.artifactId}-${prj.release.version}" addproperty="prj.release.tag" /> <input message="Please enter the project next version?" defaultvalue="${tmp.next.version}" addproperty="prj.next.version" /> <fail unless="prj.release.version" message="Property 'prj.release.version' was not defined!" /> <fail unless="prj.release.tag" message="Property 'prj.release.tag' was not defined!" /> <fail unless="prj.next.version" message="Property 'prj.next.version' was not defined!" /> </target> </project>
The “input”-target uses <artifact:pom … /> task and offers the POM structure to the ant script.
Furthermore it makes use of Ant’s possibility to embed javascript, that reads current artifact version from the POM and pre-set some default variables like release version, release tag and next development version.
Finally the second target specifies the release procedure:
<target name="release" depends="prerequisites, input" description="project release ant script"> <artifact:mvn mavenHome="${env.MAVEN_HOME}" fork="true"> <arg value="--batch-mode" /> <arg value="-Dtag=${prj.release.tag}" /> <arg value="-DreleaseVersion=${prj.release.version}" /> <arg value="-DdevelopmentVersion=${prj.next.version}" /> <arg value="clean" /> <arg value="release:prepare" /> <arg value="release:perform" /> </artifact:mvn> <available file="target/checkout" type="dir" property="checkout.dir.present" /> <fail unless="checkout.dir.present" message="Checkout directory 'target/checkout' is not present!" /> <!-- deploy 'test1' profile --> <artifact:mvn mavenHome="${env.MAVEN_HOME}" pom="target/checkout/pom.xml" fork="true"> <arg value="-Ptest1" /> <arg value="clean" /> <arg value="deploy" /> </artifact:mvn> <!-- deploy 'test2' profile --> <artifact:mvn mavenHome="${env.MAVEN_HOME}" pom="target/checkout/pom.xml" fork="true"> <arg value="-Ptest2" /> <arg value="clean" /> <arg value="deploy" /> </artifact:mvn> <!-- deploy 'prod' profile --> <artifact:mvn mavenHome="${env.MAVEN_HOME}" pom="target/checkout/pom.xml" fork="true"> <arg value="-Pprod" /> <arg value="clean" /> <arg value="deploy" /> </artifact:mvn> </target>
Because it is just a simple ant script, it can be executed either directly from your favorite IDE
or from the command line tool by calling: ant -f release.xml
Note! maven-ant-tasks-2.1.3.jar file has to be commited to the SCM together with the release.xml
In every project, there are frequently code fragments, one would like to generate on builtime instead to code by hand. This post demonstrates how to generate Java sources with Groovy as part of the Maven build lifecycle without much effort.
As an example I’ll take the RestyGWT interfaces from one of the previous posts (see GWT: Creating REST Services with Jersey and RestyGWT) and show how to generate them on build time.
Note! Using Groovy scripts it is possible to generate nearly any kind of required project sources / resouces.
Out of the box Maven already provides facilities for generating project documentation, so called Maven Sites. Very often, however, it is desirable to create a good looking, “book-style” PDF document(s) that can be delivered to the end customers for example or as self-containing project documentation. To accomplish this task, Docbook would be a good choice.
This post describes how to create/generate docbook documents from the Maven project using Docbkx Maven Plugin. Consult GitHub for the complete project sample: https://github.com/bigpuritz/javaforge-blog/tree/master/docbkx.
The sample project mentioned above is a maven artifact with a jar packaging type. It defines special profile docbkx in pom.xml, that activates docbkx-maven-plugin run (pdf generation) in the package phase. Furthermore build-helper-maven-plugin is added to this profile. It attaches (as zip) compressed pdf as artifact to the maven’s build lifecycle so that it can be installed in the maven repository on build.
Excerpt from pom.xml :
<profiles> <profile> <id>docbkx</id> <build> <plugins> <plugin> <groupId>com.agilejava.docbkx</groupId> <artifactId>docbkx-maven-plugin</artifactId> <version>2.0.14</version> <executions> <execution> <id>doc</id> <goals> <goal>generate-pdf</goal> </goals> <phase>package</phase> </execution> </executions> <dependencies> <dependency> <groupId>net.sf.xslthl</groupId> <artifactId>xslthl</artifactId> <version>2.0.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>net.sf.offo</groupId> <artifactId>fop-hyph</artifactId> <version>1.2</version> <scope>runtime</scope> </dependency> </dependencies> <configuration> <sourceDirectory>docs</sourceDirectory> <targetDirectory>target/docs</targetDirectory> <xincludeSupported>true</xincludeSupported> <useExtensions>1</useExtensions> <highlightSource>1</highlightSource> <highlightDefaultLanguage>java</highlightDefaultLanguage> <calloutsExtension>1</calloutsExtension> <paperType>A4</paperType> <fop1Extensions>1</fop1Extensions> <foCustomization>${basedir}/conf/customization-fopdf.xsl</foCustomization> <includes>manual.xml</includes> <postProcess> <zip destfile="${project.build.directory}/${project.artifactId}-${project.version}-docs.zip"> <fileset dir="${project.build.directory}/docs" includes="**/*.pdf" /> </zip> </postProcess> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.7</version> <executions> <execution> <goals> <goal>attach-artifact</goal> </goals> <phase>package</phase> <configuration> <artifacts> <artifact> <file>${project.build.directory}/${project.artifactId}-${project.version}-docs.zip</file> <type>zip</type> <classifier>docs</classifier> </artifact> </artifacts> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles>
Running a build with activated profile is quite easy:
mvn -Pdocbkx clean install
This will create following set of artifacts in the local maven repository:
And last but not least, take a look at the PDF document generated on the sample project build. This is how cool project documentation should look like :)
Note! In case of maven multi-module project it is probably a better idea to create a separate maven module with pom packaging type used for documentation only.