Java – Best Way to Structure a Git Repository for Maven

gitjavamavenversion control

I need some advice on how to structure our projects in Git. We use Java and Maven is our build tool. Maven kinda assumes all of your projects have a common ancestor eventually. Maven can also be a real drama queen when things aren't setup exactly the way the Apache foundation sets up their projects (anyone using the release plugin probably knows what I'm talking about).

We want a top level parent pom that controls plugin versions and build configuration (repo config, what artifacts to build, naming conventions, plugin versions, etc). Maven would want all of our IT projects to be in subfolders of that main project. This implies one massive Git repo for the organization.

This will make for a very noisy environment. If there are two teams working on unrelated projects, they will constantly have to pull in merges from the other team. Ideally I'd like to have one repo per project.

But that sort of clashes with the extremely hierarchal model of Maven, which demands sub-projects be sub-folders.

I need some advice on how people have reconciled these two models… thank you!

Best Answer

You have 2 options:

  1. by git way: use submodules. Here is a documentation how git manage submodules [git submodules][1]. I personally didn't use it but it looks to fit your problem.
  2. by maven way: in maven it is not mandatory that your root project (configuration) to be hierarchically the parent directory of all your projects. You can have a structure like that:
configuration
 +-- pom.xml (configuration:XXX)
project1
 +-- pom.xml (project1:1.0-SNAPSHOT)
 !
 +-- module11 
 !     +-- pom.xml (1.0-SNAPSHOT)
 +-- module12
       +-- pom.xml (1.0-SNAPSHOT)
project2
 +-- pom.xml (project2:2.0-SNAPSHOT)
 !
 +-- module21 
 !     +-- pom.xml (2.0-SNAPSHOT)
 +-- module22
       +-- pom.xml (2.0-SNAPSHOT)

configuration, project1 and project2 are on the same directory level and each one could be a git repository. When build project1 or project2 you run the maven command from project1 or project2 level and maven will try to fetch the parent (configuration) from maven repository not from parent directory. You should pay attention to versions. I would recommend in project1 or project2 to keep a reference to a parent (configuration) with a release version.

To make a release you have to do it in 2 steps: release configuration first and release project second. Project1 and project2 can evolve independently and doesn't have to have the same configuration version as a parent.

Just for special cases when you want to have both configuration and projects as SNAPSHOT versions, in project1 or project2 you can use the <relativePath> tag inside <parent> tag to point to your local path of configuration. I don't recommend this because will create problems on development environment (at least for me in Eclipse)

I apologize for my English. [1]: http://git-scm.com/book/en/Git-Tools-Submodules