Step By Step Guide for v4.X

From mvn-pkg-plugin (inactive) Wiki
(Redirected from Step By Step Guide)
Jump to: navigation, search

Contents

Basics

Setting up the environment

First of all, in order to use the plugin, we will need to configure the evolvis maven plugin repository in our ~/.m2/settings.xml, or in the pom.xml of our project. (For more detailed information, see Downloads)

 <pluginRepositories>
    <pluginRepository>
        <id>evolvis-release-repository</id>
        <name>evolvis.org release repository</name>
        <url>http://maven-repo.evolvis.org/releases</url>
        <snapshots>
          <enabled>false</enabled>
         </snapshots>
    </pluginRepository>
 </pluginRepositories>

Writing a (very simple) first configuration

Once maven is able to download the plug-in from the evolvis maven repository, you will need to add the plug-in to the plugins section of your pom.xml.

<plugins>
	[...]
	<plugin>
		<groupId>de.tarent.maven.plugins</groupId>
		<artifactId>maven-pkg-plugin</artifactId>
		<version>4.0.3</version>
		<configuration>
			<!-- We will be adding configuration parameters here in a second -->
		</configuration>
	</plugin>
	[...]
</plugins>

The mvn-pkg-plugin reads targetConfigurations, and uses the information contained in them during the execution of the goals it provides. For the next steps we will use the main goal provided by the plugin: pkg:pkg.

In this example, we will define a targetConfiguration in order to create a debian package for the distribution Ubuntu Lucid. We will call this targetConfiguration "myFirstPackage".

<plugins>
	[...]
	<plugin>
		<groupId>de.tarent.maven.plugins</groupId>
		<artifactId>maven-pkg-plugin</artifactId>
		<version>4.0.3</version>
		<configuration>
			<target>myFirstPackage</target>
			<targetConfigurations>
				<targetConfiguration>
					<target>myFirstPackage</target>
					<distros>
						<distro>ubuntu_lucid</distro>
					</distros>
				</targetConfiguration>
			<targetConfigurations>
		</configuration>
	</plugin>
	[...]
</plugins>

One or many targetConfigurations can be defined within the <targetConfigurations> tags. We have written a <target> element at the beginning of the configuration section to define the targetConfiguration(s) that will be executed when pkg:pkg is executed. This element can also contain a comma separated list of targetConfigurations to execute.

A target configuration can be suitable for different distributions, that's why we wrote the "ubuntu_lucid" <distro> element between within the <distros> tags.

For simplicity from now on we will only show the configuration section of the plugin, to improve readability of the examples.

Running the pkg:pkg goal

Now we will just run the pkg:pkg goal from the command line and have a look at the contents of the resulting package:

$ mvn pkg:pkg

Under the project's target folder we will find a deb file with the following naming convention:

lib-${artifactId}-java_${version}_${architecture}.deb

Packages generated without specifying a section (in rpm lingo group tag) are automatically handled as if they were libraries. That is where the "lib-" and the extra "-java" strings come from.

Lets have a look at the contents of the package:

├── DEBIAN
│   └── control
└── usr
    └── share
        └── java
            └── Artifact.jar

These would be the minimum number of files contained in your package. If your pom.xml contains information about a license, this would be stored under the DEBIAN directory, in the copyright file.

The artifact resulting of compiling our sample project is a jar, and it has been packaged in such a way, that it will be copied to the default location of jar files in the Ubuntu Lucid distribution.

Let's have a look at the control file (when creating rpm files, you'd need to run rpm -pq --info to access this information)

Package: libsampleproject-java
Version: 1.0.0
Section: libs
Depends: java2-runtime
Priority: optional
Architecture: all
Installed-Size: XX
Description: Sample Description
 Sample Description
  • Here we can see that the section of the package is, as mentioned above this lines, in fact "libs".
  • As of version 4 of the mvn-pkg-plugin, all packages built with it have at least the JRE as a dependency. If the project you are following this instructions with has certain maven dependencies, the plugin would have tried to resolve them in native dependencies of the Lucid ecosystem. If it did not find a match for any of them, he will have included them inside the package.
  • The architecture of this package has been set to all.
  • The description, as many other possible fields, is automatically generated from the pom.xml description element.

On the next step we will add more meta-data to this package.

Adding other simple parameters to our configuration

Back to the pom.xml file, we will modify our target configuration to include a package maintainer, make the package belong to the "devel" section, will add a custom suffix to the version (to indicate that this specific version of the package is meant for the Quality Assurance group), and will force the architecture of the package to amd64:

<targetConfiguration>
    <target>myFirstPackage</target>
    <distros>
        <distro>ubuntu_lucid</distro>
    </distros>
    <maintainer>Mr. Maintainer Junior &lt;no@address.com&gt;</maintainer>
    <section>devel</section>
    <packageVersionSuffix>qa</packageVersionSuffix>
    <architecture>amd64</architecture>
</targetConfiguration>

After running pkg:pkg on our sample project we obtain now following package on the target folder:

sampleproject_1.0.0-0qa_amd64.deb

As you can see, the "lib-" and "-java" parts that we obtained during the previous step of this guide are gone, as we set the section to "devel" in our configuration. Also the "qa" suffix has been attached to the version number (notice the extra "-0": parts of the version number are not allowed to start with a non numeric character).

Now to our control file inside the package:

Package: dummyproject
Version: 1.0.0-0qa
Section: devel
Depends: java2-runtime
Priority: optional
Architecture: amd64
Installed-Size: XXX
Maintainer: Mr. Maintainer Junior <no@address.com>
Description:  Sample Description
 Sample Description
  • The version number has also been modified inside this file.
  • The architecture of the file has also been forced to amd64.
  • The maintainer field has been populated with the one provided in the pom.

Adding external files

In this step we will include an external file (the logo of our sample project) to the final package:

<targetConfiguration>
 	<target>myFirstPackage</target>
 	<distros>
 	<distro>ubuntu_lucid</distro>
 	</distros>
 	<maintainer>Mr. Maintainer Junior &lt;no@address.com&gt;</maintainer>
 	<section>devel</section>
 	<packageVersionSuffix>qa</packageVersionSuffix>
 	<architecture>amd64</architecture>
 
	<dataFiles>
	 	<dataFile>
	 		<from>logo.png</from>
	 		<to>images/</to>
	 	</dataFile>
	</dataFiles>
 
</targetConfiguration>

In the mvn-pkg-plugin auxiliary files (auxFiles) can be defined for inclusion in the final package. dataFile is a kind of auxFile. auxFiles need to be stored under "src/main/auxfiles" for the plug-in to be able to use them.

For further auxFile types and their features, please refer to the User Manual.

These are the contents of the resulting package after running pkg:pkg :

├── DEBIAN
│   └── control
└── usr
    └── share
        ├── ${artifactId}
        │   └── images
        │       └── logo.png
        └── java
            └── Artifact.jar

Adding dependencies manually

As we have learned, mvn-pkg-plugin resolves all maven dependencies your project may have into the target packaging system dependencies. Let's say that we want to make our package also dependent on gdm.

<targetConfiguration>
 	<target>myFirstPackage</target>
 	<distros>
 	<distro>ubuntu_lucid</distro>
 	</distros>
 	<maintainer>Mr. Maintainer Junior &lt;no@address.com&gt;</maintainer>
 	<section>devel</section>
 	<packageVersionSuffix>qa</packageVersionSuffix>
 	<architecture>amd64</architecture>
	<dataFiles>
	 	<dataFile>
	 	 	<from>logo.png</from>
	 	 	<to>images/</to>
	 	</dataFile>
	</dataFiles>
 
	<manualDependencies>
	 	<string>gdm</string>
	</manualDependencies>
 
</targetConfiguration>

All manualDependencies must match exactly the name of the package in the target package system for it to work properly.

Here is the control file of the resulting package after running pkg:pkg :

Package: dummyproject
Version: 1.0.0-0qa
Section: devel
Depends: java2-runtime, gdm
Priority: optional
Architecture: amd64
Installed-Size: XXX
Maintainer: Mr. Maintainer Junior <no@address.com>
Description:  Sample Description
Sample Description

Adding pre/post(un)installation scripts

If you need to run a script before/after your package is (un)installed, you can use the elements preinstScript, prermScript, postinstScript and postrmScript to configure this behaviour.

In the following

<targetConfiguration>
 	<target>myFirstPackage</target>
 	<distros>
 	<distro>ubuntu_lucid</distro>
 	</distros>
 	<maintainer>Mr. Maintainer Junior &lt;no@address.com&gt;</maintainer>
 	<section>devel</section>
 	<packageVersionSuffix>qa</packageVersionSuffix>
 	<architecture>amd64</architecture>
	<dataFiles>
	 	<dataFile>
	 	 	<from>logo.png</from>
	 	 	<to>images/</to>
	 	</dataFile>
	</dataFiles>
	<manualDependencies>
	 	<string>gdm</string>
	</manualDependencies>
 
	<preinstScript>myPreInstallScript</preinstScript>
 
</targetConfiguration>

As with auxFiles, these scripts must be located under "src/main/auxfiles" for the plugin to find them.

Here is the control file of the resulting package after running pkg:pkg :

├── DEBIAN
│   ├── control
│   └── preinst
└── usr
    └── share
        ├── ${artifactId}
        │   └── images
        │       └── logo.png
        └── java
            └── Artifact.jar

The preinst script will contain some automatically generated variables for the script to use, and then attach the contents of the script we want to execute:

#!/bin/sh
# This script is partly autogenerated by the de.tarent.maven.plugins.pkg.helper.Helper class
# of the maven-pkg-plugin. The autogenerated part adds some variables of the packaging
# to the top of the script which can be used in the lower manual part.
 
prefix="/"
bindir="/usr/bin"
datadir="/usr/share/sampleProject"
datarootdir="/usr/share"
sysconfdir="/etc"
[...]
jnidir="/usr/lib/jni"
scriptType="pre-install"
 
distro="ubuntu_lucid"
distroLabel="Ubuntu 10.04 (Lucid Lynx)"
packaging="deb"
 
# What follows is the content script file myPreInstallScript
 
# Some commands

Adding a wrapper script

The mvn-pkg-plugin provides the posibility to add a wrapper script to your package, in order to execute the artifact within as a standalone application.

This is fairly easy, you just need to add the name of your main class to the target configuration:

<targetConfiguration>
 	<target>myFirstPackage</target>
 	<distros>
 	<distro>ubuntu_lucid</distro>
 	</distros>
 	<maintainer>Mr. Maintainer Junior &lt;no@address.com&gt;</maintainer>
 	<section>devel</section>
 	<packageVersionSuffix>qa</packageVersionSuffix>
 	<architecture>amd64</architecture>
	<dataFiles>
	 	<dataFile>
	 	 	<from>logo.png</from>
	 	 	<to>images/</to>
	 	</dataFile>
	</dataFiles>
	<manualDependencies>
	 	<string>gdm</string>
	</manualDependencies>
	<preinstScript>myPreInstallScript</preinstScript>
 
	<mainClass>org.evolvis.sampleProject.Main</mainclass>
 
</targetConfiguration>

The generated script is executable and will be found under the "bindir" of the distribution we are packaging for.

├── DEBIAN
│   ├── control
│   └── preinst
└── usr
    ├── bin
    │   └── java
    │       └── ${artifactId}
    └── share
        ├── ${artifactId}
        │   └── images
        │       └── logo.png
        └── java
            └── Artifact.jar

Signing your package

Based on the name of the maintainer provided in your configuration and its pgp key, deb and rpm packages can be automatically signed by the mvn-pkg-plugin. Besides the name of the maintainer, the element <sign> must be set to true in your target configuration.

<targetConfiguration>
 	<target>myFirstPackage</target>
 	<distros>
 	<distro>ubuntu_lucid</distro>
 	</distros>
 	<maintainer>Mr. Maintainer Junior &lt;no@address.com&gt;</maintainer>
 	<section>devel</section>
 	<packageVersionSuffix>qa</packageVersionSuffix>
 	<architecture>amd64</architecture>
	<dataFiles>
	 	<dataFile>
	 	 	<from>logo.png</from>
	 	 	<to>images/</to>
	 	</dataFile>
	</dataFiles>
	<manualDependencies>
	 	<string>gdm</string>
	</manualDependencies>
	<preinstScript>myPreInstallScript</preinstScript>
	<mainClass>org.evolvis.sampleProject.Main</mainclass>
 
	<sign>true</sign>
 
</targetConfiguration>

If there is an encryption keys agent running on the machine, and the private key is for the maintainer can be used by it, the process will be transparent.

Alternatively the password for the key can be assigned through the property signPassPhrase, thus being able to sign a package through the command line like this:

$ mvn pkg:pkg -DsignPassPhrase=SuperSecretKey

Advanced configurations

Uploading/copying the resulting package file to another location

The installation package resulting of pkg:pkg can also be automatically uploaded or copied to a different location of your choice, by using the pkg:upload goal and providing an uploadParameters section in your targetConfiguration:

<targetConfiguration>
 	<target>myFirstPackage</target>
 	<distros>
 	<distro>ubuntu_lucid</distro>
 	</distros>
 	<maintainer>Mr. Maintainer Junior &lt;no@address.com&gt;</maintainer>
 	<section>devel</section>
 	<packageVersionSuffix>qa</packageVersionSuffix>
 	<architecture>amd64</architecture>
	<dataFiles>
	 	<dataFile>
	 	 	<from>logo.png</from>
	 	 	<to>images/</to>
	 	</dataFile>
	</dataFiles>
	<manualDependencies>
	 	<string>gdm</string>
	</manualDependencies>
	<preinstScript>myPreInstallScript</preinstScript>
	<mainClass>org.evolvis.sampleProject.Main</mainclass>
	<sign>true</sign>
 
 
	<uploadParameters>
	 	<url>scpexe://remoteserver/remotedir</url>
	</uploadParameters>
 
</targetConfiguration>

Abailable uri schemas are those provided by the maven wagon api (although only webdav://, file://, scmexe:// and ftp:// have been tested by the mvn-pkg-plugin team) and dupload://, through which debian packages can be uploaded to apt repositories (by using the "dupload" tool, hence its name).

How to inherit from other configurations

The mvn-pkg-plugin supports inheritance among targetConfiturations, thus providing good flexibility for building several kinds of packages at once, and avoiding redundancy when defining new targetConfigurations.

TargetConfigurations can be linked to each other in a parent-child relationship using the <parent> element:

<targetConfiguration>
 	<target>genericTarget</target>
 	<distros>
 	 	<distro>ubuntu_lucid</distro>
 	 	<distro>ubuntu_karmic</distro>
 	 	<distro>centos_5_6</distro>
 	</distros>
</targetConfiguration>
 
<targetConfiguration>
 	<target>genericUbuntuTarget</target>
 	<parent>genericTarget</target>
 	<distros>
 	 	<distro>ubuntu_lucid</distro>
 	 	<distro>ubuntu_karmic</distro>
 	</distros>
</targetConfiguration>
 
<targetConfiguration>
 	<target>lucidTarget</target>
 	<parent>genericUbuntuTarget</target>
 	<distros>
 	 	<distro>ubuntu_lucid</distro>
 	</distros>
</targetConfiguration>
 
<targetConfiguration>
 	<target>karmicTarget</target>
 	<parent>genericUbuntuTarget</target>
 	<distros>
 	 	<distro>ubuntu_karmic</distro>
 	</distros>
</targetConfiguration>
 
<targetConfiguration>
 	<target>centosTarget</target>
 	<parent>genericTarget</target>
 	<distros>
 	 	<distro>centos_5_6</distro>
 	</distros>
</targetConfiguration>

The above configuration describes the following hierarchy:

              centosTarget
             /
genericTarget                     lucidTarget
             \                   /
              genericUbuntuTarget
                                 \
                                  karmicTarget

This way we could provide very generic configuration options for all targets at the genericTarget level (i.e. common external files needed by all). Then something specific for all ubuntu distributions in genericUbuntuTarget and once more, more specific features for lucid and karmic (i.e. specific preinstallation scripts).

All elements defined under the "Basic" section of this guide will be merged when resolving the dependencies among targetConfigurations. For further insight on the default value for each possible element, please refer to the User Manual.

Splitting code and configuration: horizontal relationships

In this example we will simulate creating a package which will contain only configuration for our application, and another one that will contain the application itself:

<targetConfiguration>
       <target>packageForApplication</target>
               <distros>
                     <distro>ubuntu_lucid</distro>
               </distros>
</targetConfiguration>
 
<targetConfiguration>
       <target>packageContainingOnlyConfig</target>
               <artifactInclusion>none</artifactInclusion>
               <distros>
                     <distro>ubuntu_lucid</distro>
               </distros>
 
               <relations>
                  <relation>packageForApplication</relation>
               </relations>
 
               <packageNameSuffix>config</packageNameSuffix>
 
</targetConfiguration>

The first configuration is for the code and it contains no new items. The second configuration however disables the inclusion of any artifacts (read jars) by setting the artifactInclusion parameter to none. The binary package will thusly not contain the project's main artifact nor its dependencies. In order to ease package creation the configuration also contains a depedency (called relation) to the first one. By doing so the first configuration will be built before and it ends up in the dependency of the second configuration's binary package.