maven multi module project: is relativepath necessary? - maven

I'm trying to link together a set of disjoint maven projects into a standard multi module project.
The interesting thing is that the modules are currently not arranged in a natural heirarchy. If I link together with a parent pom, then the reactor won't start up until I add relativePaths to the parent stanza in the child pom XML files.
If the GAV details are correct in the parent version vs the child, and the child modules are all linked in the parent pom - shouldn't this be enough?
in simple terms - for a non-standard directory structure, is the relativePath strictly necessary for a multi module maven project?
Thanks, Ace

in simple terms - for a non-standard directory structure, is the relativePath strictly necessary for a multi module maven project?
The answer is: Yes!
If the parent is not yet installed in the local repository and if the directory structure is for example:
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
The child modules cannot inherit the groupId / version of their parent POM without setting the <relativePath> element.
See http://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Example_2

Related

version updates while updating maven inherited properties

I have multiple maven multi-module projects and one parent project. Parent project pom.xml file is the parent of all other projects' root pom.xml.
-> ParentProject
pom.xml
->Project1
-> module1
src
pom.xml
-> module2
src
pom.xml
->pom.xml
->Project2
-> module1
src
pom.xml
-> module2
src
pom.xml
->pom.xml
In the parent pom.xml file, I have a couple of properties which are inherited and used by others. I need to update those properties quite frequently, and if I increase the version of parent pom after updating those properties, I need to update other poms and increase their versions as well. Is there any way to prevent it, or is there a better way to do it? Thanks!
You can use the versions plugin to help with the tedium: Update the ParentProject version (and install locally) and then run mvn versions:update-parent to update the parent version in Project1 and Project2.
There are other useful targets for updating properties and dependencies.

Sharing plugin versions between reactor and parent pom in a multi-module maven project

I have a multi-module maven project with a reactor pom that I use to build the whole project, and a parent pom which all child modules inherit from.
There is a plugin I need to have in both the reactor and the parent poms, meaning I have a separate use for the plugin in the child modules and in the reactor pom used to aggregate the build. I'd like to manage the version of this plugin in one file, instead of manually changing it in both files every time.
Example:
Project structure:
--pom.xml //reactor pom - aggregates the build (contains the plugin)
----parent/pom.xml //parent pom - all child modules inherit this pom (contains the plugin)
----a/pom.xml //module a - inherits parent/pom.xml
----b/pom.xml //module b - inherits parent/pom.xml
----c/pom.xml //module c - inherits parent/pom.xml
Note: the parent pom is inherited by child modules only. Not by the reactor.
any help is greatly appreciated, thanks in advance

Maven project structure

In svn repository I have a folder 'product' under which are all my Eclipse plugins and features, parallel to these there is parent POM. This setup works well when I build in Jenkins, I just check out 'product' and install pom.xml. However, I can't figure out how this setup works in Eclipse workspace? I can't check out pom.xml by itself into workspace, and if I do I need to check it out as single file under a project which brakes path to parent POM. How should I check out and build in such setup?
Also, do I need to define relativePath of parent POM in my plugins? I found that if I omit it, then I get error about path being missing.
Just to summarize, my svn repository structure is this:
repo/
trunk/
product <- maven project (folder with .project set as maven nature)
pluginA
pluginB
featureA
pom.xml
.project
I think you have two options:
Deploy your parent POM to a locally available repository, perhaps your company Nexus server, for example? This will then be available to all products and for all your colleagues.
Restructure your project to look more Maven-like, e.g.
|-- plugin1
|-- pom.xml
|-- ....
|-- plugin2...
|-- feature1...
|-- ...
pom.xml <-- parent POM
This second option may be better in the long term, otherwise your Jenkins server relies on you remembering to locally install the updated parent POM, rather than just plucking it from svn.
If you use m2eclipse (e.g. available from the Juno site), you can import any Maven project structure into Eclipse. In your case, the product folder would be imported as an Eclipse project, as well as the individual features and bundles.
<relativePath> defaults to .., so you need to specify it if the parent POM is not in the parent folder. You can set it to undefined (e.g. through an empty <relativePath/> tag) if the parent POM is not available locally. In this case, Maven will always resolve the parent POM from the local Maven repository or the configured remote (Maven) repositories.

Packaging multi-platform multi-module maven project

I'm participating in an open source project (ps3mediaserver) which has been moved from google code (SVN) and ANT (for build tasks) to git (GitHub) and maven. I've got my own fork (called pms-mlx), where I'd like to maintain some plugins being part of the default packaging when releasing. I'm pretty new to maven and am not too sure how the project should be structured to respect the maven way.
I'll start by describing how the environment behaved previously and will then give the thoughts about the move to maven.
Links:
Old: SVN + ANT ps3mediaserver project on google code
Old: SVN + ANT pms-mlx project on SourceForge
New: Git + Maven ps3mediaserver project on GitHub
New: Git + Maven pms-mlx project on GitHub
Old behavior:
Project structure:
+--workspace
+--plugins
+--plugin1
build.xml
+--plugin2
build.xml
+--ps3mediaserver_mlx
+--plugins
build.xml
The main project is ps3mediaserver_mlx, all plugins live in sub-folders of the workspace/plugins folder.
ps3mediaserver_mlx/build.xml contains a target BuildWithoutLibs which will build the jar of the main project and copy it to workspace/pms_no_libs.jar which will then be referenced (at this location) by the plugins.
When executing the build target of any plugin, the plugin will be build and the resulting jar copied to ps3mediaserver_mlx/plugins/[plugin_name].jar.
And finally, when packaging the application using the the build target in ps3mediaserver_mlx/build.xml, the plugins containedin workspace/ps3mediaserver_mlx/plugins will be packaged (in a exe installer for windows, dmg for OSX or tar.gz for linux).
New behavior
The project structure has been changed to this:
+-- workspace/
+-- pom.xml (global-pom)
+-- ps3mediaserver/
| +-- pom.xml (pms-pom)
| +-- src/
| ...
+-- plugins/
| +-- pom.xml (plugins-pom)
| +-- Plugin1/
| pom.xml (plugin1-pom)
| src/
| +-- Plugin2/
| pom.xml (plugin2-pom)
| src/
+-- pms-package/
+-- pom.xml (package-pom)
+-- src/main/assembly/
+-- src/main/external-resources/
Responsabilities:
global-pom The root pom containing all dependencies used by pms. This lets use the same version without redeclaring them in any plugin (is this a good idea?). Builds everything and contains a modules section to perform the same maven commands on all projects
<modules>
<module>ps3mediaserver</module>
<module>plugins</module>
<module>pms-package</module>
</modules>
pms-pom: Inherits from global-pom andbuilds the pms jar
plugins-pom: Inherits from global-pom; contains a depency for pms (which will be required for all plugins); contains a list of all modules having to be built
pluginX-pom: Inherits from plugins-pom and contains a custom configuration for a plugin
package-pom: Is responsible to package pms according to the platform it is being built on.
Does this structure represent the way maven is ment to be used?
Everything is working up to the packaging. This means the main application jar as well as all the plugins have been built and need to be packaged. The package-pom is responsible to do that.
In the original application there is only one pom.xml and the packaging is being done by using different profiles for Windows, Linux and OS X. The one I'm currently working on is for OSX and uses osxappbundle-maven-plugin, but the source code is never being packaged in the app file. That's because the packaging project doesn't inherit from the actual project anymore.
How has the built jar to be referenced in order to be packaged correctly in the app file?
I've tried referencing the jar in additionalResources and as custom class path, but never with success.
You have defined a dependency for example in the plugins/pom.xml
<dependencies>
<dependency>
<groupId>net.pms</groupId>
<artifactId>pms-mlx</artifactId>
<version>1.52.1_mlx_v0.8-SNAPSHOT</version>
</dependency>
</dependencies>
which exactly represents your parent. In other words it's wrong to define a dependency which already been defined as your parent.
It's good practice to put the modelVersion tag directly after the project tag and before the parent tag. After the parent tag put the information the current module like artifactId.
After diving into the project i noticed that you defined in your of your plugins/WebservicePlugin:
<modelVersion>4.0.0</modelVersion>
<artifactId>WebservicePlugin</artifactId>
<version>3-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>net.pms</groupId>
<artifactId>pms-plugins</artifactId>
<version>1.52.1_mlx_v0.8-SNAPSHOT</version>
</parent>
which is against the maven way for multi-module builds. You should not define a different version in this case. It should look like this:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.pms</groupId>
<artifactId>pms-plugins</artifactId>
<version>1.52.1_mlx_v0.8-SNAPSHOT</version>
</parent>
<artifactId>WebservicePlugin</artifactId>
If you have problems based on the version of the WebservicePlugin module than you should think about separating the WebservicePlugin from the rest (may be the other plugins as well).
One other things which i have noticed that you defined in many of the plugins (if not all of them) the configuration and the usage of the maven-compiler-plugin...This should be done by using a pluginManagement part in your root pom...to simplyfy maintenance of your project.
The copying of the created plugins-jars via the maven-antrun plugin into a different location whould be done different.
Repeating the license entry in every plugin is not needed cause it's inherited by the parent.

multi-module project and ${basedir} placeholder

I have a multi module project with the following structure:
-parent
-module1
-module2
-src
-main
-javadoc
-stylesheet.css
-pom.xml
I want to configure the javadoc plugin in the parent POM. But, I need to specify the path to the stylesheet.css file. So, I use the value ${basedir}\src\main\javadoc\stylesheet.css.
But, when I look at the effective POM for the child modules, the ${basedir} is replaced by the absolute path of the child module base directory, but there is no src/main/javadoc/stylesheet.css file there. Copying the stylesheet.css file in the child modules is not a solution, I think.
Thanks
${basedir} (short for ${project.basedir}) is a directory where project's pom.xml file resides. Therefore, for child modules this property is going to contain paths to module1 and module2 directories correspondingly.
If you want to configure javadoc plugin in the parent pom.xml so it would be effective for child modules, you should use ../src/main/javadoc/stylesheet.css.
The Maven Javadoc plugin allows you to include stylesheet resources that are stored in a JAR file, as described here: http://maven.apache.org/plugins/maven-javadoc-plugin/examples/stylesheet-configuration.html
This would allow you to create a resource-only JAR, add it to the dependencies list for your javadoc plugin, and load the resources from there. This would eliminate the need to either duplicate stylesheet files, or reference a shared set deployed in your parent POM.

Resources