Issue
Many Java libraries have already been packaged in Debian, but they don't have any Maven descriptors (POMs) associated with them. The Maven Debian helper package helps packaging Java software built with Maven, but in order to work it requires that all dependencies have their Maven POMs installed in /usr/share/maven-repo.
In addition, smooth upgrade of Java libraries would imply some difficult search & replace operations in the Maven repository, unless the proposal in Maven Repo Specification is adopted. This proposal suggest creating both native and Debian versions of the artifacts, and replacing all versions in the dependencies with Debian versions.
The maven-repo-helper package aims to provide tools for installing and maintaining POMs and jars in /usr/share/maven-repo, and will have no dependency on Maven so it can be used for any library. It provides the foundations for Maven Debian helper.
Features
For example, get the latest sources of libplexus-io-java using
- apt-get source libplexus-io-java
This library uses maven-repo-helper for installing its POM and jar files in /usr/share/maven-repo.
The debian/rules contain
binary-post-install/lib$(PACKAGE)-java:: mh_installpoms -plib$(PACKAGE)-java mh_installjar -plib$(PACKAGE)-java -l pom.xml build/$(PACKAGE)-$(VERSION).jar clean:: mh_clean
and the Build-Depends are
Build-Depends-Indep: maven-repo-helper, maven-ant-helper, libplexus-utils-java, libplexus-container-default-java
No patches for the POM files are needed, all is taken care of by the mh_installpom script (which uses mh_cleanpom)
mh_installpoms will install all POM files registered in debian/$package.pom into /usr/share/maven-repo,
mh_installjar will install the jar file associated with the POM into /usr/share/maven-repo and also add a link to the jar in /usr/share/java, with and without the version
Additional files which may be required are:
debian/$bin-package.poms (for example, debian/libplexus-io-java.pom)
pom.xml --no-parent
It simply lists the pom files in the source tree which need to be installed in the repository, and indicates with the --no-parent option that if the POM inherits from a parent POM, then this inheritance relationship will be removed in the cleaned POM. Removing the parent inheritence can often simplify the packaging, as the parent POM mostly does not contain any useful information - we need only the list of dependencies in our repository, the other details for the build are irrelevant.
A more complex example from the modello package is:
pom.xml --no-parent modello-core/pom.xml modello-plugins/pom.xml modello-plugins/modello-plugin-converters/pom.xml modello-plugins/modello-plugin-dom4j/pom.xml modello-plugins/modello-plugin-java/pom.xml modello-plugins/modello-plugin-jdom/pom.xml modello-plugins/modello-plugin-stax/pom.xml modello-plugins/modello-plugin-xdoc/pom.xml modello-plugins/modello-plugin-xml/pom.xml modello-plugins/modello-plugin-xpp3/pom.xml modello-plugins/modello-plugin-xsd/pom.xml
debian/maven.rules
The format for rules files is:
groupId artifactId type version classifier scope
which refers to the parts of dependency stanzas in pom.xml like:
<dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-plugin-testing-harness</artifactId> <version>1.0-beta-1</version> <scope>test</scope> </dependency>
Each item can contain a match, a substitution or a wildcard
type is normally jar, pom or *
trailing items can be omitted - which is equivalent to putting *
For example:
junit junit jar s/3\..*/3.x/
This file is taken from the modello package. It specifies that the dependency on junit will use the version '3.x' instead of the default 'debian' version if the native version starts with '3.'. If the group id of the dependency is 'junit, the artifact id of the dependency is 'junit', the type of the dependency is 'jar' and the version starts with '3.', then this rule is used. 's/3\..*/3.x/' performs the replacement for the version, the syntax should be obvious to any sed user.
This example from the commons-configuration package shows a few more possibilities: here, the version for commons-collections is converted to '2.x' if it starts with '2.' or '3.x' if it starts with '3.'. The line with ant is more interesting: if the group id is 'ant', then it is converted to 'org.apache.ant' - great trick for dealing with artifacts which are coming from Maven 1. Any artifact id or type will be matched and left unchanged, while the version will be converted to 'debian'. There is also the line with javax.servlet: this line keeps the version number used by this dependency, so if 2.4 is used, then 2.4 is also used in the cleaned POM.
junit junit jar s/3\..*/3.x/ commons-collections commons-collections jar s/2\..*/2.x/ commons-collections commons-collections jar s/3\..*/3.x/ s/ant/org.apache.ant/ * * s/.*/debian/ log4j log4j jar s/1\.2\..*/1.2.x/ javax.servlet servlet-api jar *
Helper scripts
mh_lspoms
Usage:
mh_lspoms [option]... <package>
Looks for all POM files defined in the source of the project.
Where
<package> is the name of the binary package,
- e.g. libcommons-lang-java. Default to the first binary found in the debian/control file
Options:
- -h --help: show this text -V --version: show the version
You need to execute it on the unpacked origial source tree, merged with the debian/ folder. It will create the file debian/<binary package>.poms which contains all the POMs to deploy to the Maven repository and is used by mh_installpoms.
The contents of debian/<binary package>.poms should be:
- one POM file location per line,
- optionaly, the location is followed by the option --no-parent
- to indicate that if this POM inherits from a parent, the parent element will be removed.
mh_cleanpom
Usage:
mh_cleanpom [option]... [pom] [target] [pom-props]
Cleans the POM and prepare it for inclusion in the Maven repository. Also extracts some information from the POM.
Where
- [pom] is the location of the POM file to clean.
- Default to pom.xml or debian/pom.xml
- Default to debian/tmp/pom.xml
- Default to debian/tmp/pom.properties
Options:
- -h --help: show this text -V --version: show the version
-p<package> --package=<package>: package to act on -o --no-parent: don't inherit from a parent POM -k --keep-pom-version: keep the original version of the POM but,
- convert all other versions in dependencies and plugins
-r<rules> --rules=<rules>: gives the location of the rules file for
- special properties. Optional, the default location is debian/maven.rules
This script cleans the original Maven POM, removes all unnecessary elements, and replaces version numbers in dependencies by the Debian versions. It will also remove the POM inheritance is --no-parent is given.
debian/maven.rules is used to alter the version properties for the library and its dependencies.
This script is used by mh_installpom, normally you don't need to use it directly, except if you need to investigate an issue with the cleaning process for a POM file.
mh_installpom
Usage:
mh_installpom [option]... [pom]
Installs the POM file in /usr/share/maven-repo, at the correct location for Maven. Before installing the POM, it prepares it with mh_cleanpom.
debian/maven.rules is used to alter the version properties for the library and its dependencies.
Prefer to use mh_installpoms as it reuses the information in debian/$package.poms and avoids repetition.
Where
- [pom] is the location of the POM associated with the jar to install.
?GroupId, artifactId and version will be extracted from this file.
Options:
- -h --help: show this text -V --version: show the version
-p<package> --package=<package>: package to act on -o --no-parent: don't inherit from a parent POM -r<rules> --rules=<rules>: gives the location of the rules file for
- special properties. Optional, the default location is debian/maven.rules
This script installs the POM file in /usr/share/maven-repo, at the correct location for Maven. Before installing the POM, it prepares it with mh_cleanpom.
debian/maven.spec is used to alter the version properties for the library and its dependencies.
Prefer to use mh_installpoms as it reuses the information in debian/$package.poms and avoids repetition.
mh_installpoms
Usage:
mh_installpoms [option]...
Reads the file debian/$package.poms and installs each POM file listed in the .poms file.
Options:
- -h --help: show this text -V --version: show the version
-p<package> --package=<package>: package to act on -r<rules> --rules=<rules>: gives the location of the rules file for
- special properties. Optional, the default location is debian/maven.rules
mh_installjar
Usage:
mh_installjar [option]... [pom] [jar] [link]...
Installs the jar file in /usr/share/maven-repo, at the correct location for Maven. Both the native version and the Debian version of the jar are installed. It can also create additional links to the jar, usually placed in /usr/share/java.
Where
- [pom] is the location of the POM associated with the jar to install.
?GroupId, artifactId and version will be extracted from this file.
- folder.
- be a link to usr/share/java/.jar and usr/share/java/-.jar to comply with the Java packaging guidelines. Note that there is no need to specify those particular links if the --java-lib option is used.
Options:
- -h --help: show this text -V --version: show the version
-p<package> --package=<package>: package to act on -r<rules> --rules=<rules>: gives the location of the rules file for
- special properties. Optional, the default location is debian/maven.rules
- /usr/share/java to comply with the Java specification. More precisely, the links created will be /usr/share/java/-.jar and /usr/share/java/.jar
-n<name> --usj-name=<name>: Optional, the name to use when installing the
- library in /usr/share/java when --java-lib is used. Defaults to the artifact id found in the POM.
-i<version> --usj-version=<version>: Optional, the version to use when
- installing the library in /usr/share/java when --java-lib is used. Defaults to the version found in the POM.
mh_patchpoms
Usage:
mh_patchpoms [option]...
Reads the file debian/$package.poms and tranform each POM file listed in the .poms file into a POM file using the Debian versions of the libraries. Also keeps a backup of each POM file which can be restored with mh_unpatchpoms
Options:
- -h --help: show this text -V --version: show the version
-p<package> --package=<package>: package to act on -r<rules> --rules=<rules>: gives the location of the rules file for
- special properties. Optional, the default location is debian/maven.rules
- convert all other versions in dependencies and plugins
This script is used internally by maven-repo-helper when building packages with Maven. It is not usually used when Ant is used for the build.
mh_unpatchpoms
Usage:
mh_unpatchpoms [option]...
Restore the POM files that have been patched to their original content.
Options:
- -h --help: show this text -V --version: show the version
-p<package> --package=<package>: package to act on -v --verbose: show more information while running -n --no-act: don't actually do anything, just print the results
mh_clean
Cleans the temporary files created by the other mh_* utilities. Add it to the clean: target in debian/rules
Typical workflow
- Get the original sources and unpack them, copy the debian/ folder if you are working on an existing package.
- Fill debian/changelog and debian/control
- mh_lspoms
- edit debian/$package.poms (to check that only the POM that are needed are present, and maybe to fix the --no-parent options)
- mh_make --ant
- edit debian/rules (to fix the last remaining packaging details)
- edit debian/control (to add maven-repo-helper to Build-Depends: )