20

I am working on a Spring-MVC application in which we are using Maven for dependency management. As the project is big, we are thinking of splitting the project into several parts. I had some doubts, which I hopefully will get answers here.

Currently, we are deploying a single WAR file as ROOT.war on Apache tomcat on our server. As the project is big, there are parts in the webapp like Notifications and Email, Third party services, PUSH (Cometd),REST API's, etc. Currently all of them are clubbed and are dependent on each other. For example, Notification object also depends on Person object, as Notifications are tailored for users.

The main intention of splitting the big project is to be able to work on individual modules, for bug fixes, adding features, testing, etc. And when satisfied, then only this module can be replaced on the server instead of the entire application. Is this possible?

As I already mentioned before, there are dependencies and mappings between objects. How will those be managed across different sub-modules, or will just the import statements change to include other projects?

As I said, the intention is to work on individual modules and be able to deploy them(preferably hot). Currently, we have only a single WAR file as ROOT.war. Will splitting create multiple war files, which are then referred by URL as domain-name.com/module_name/some_mapping?

I am currently checking the documentation, but this is the primary objective we want to achieve with multi module provided by Maven and interested to know if this is feasible. If there is any more information required, please let me know.

Currently I am using a parent POM from spring as follows:

<parent>
    <groupId>io.spring.platform</groupId>
    <artifactId>platform-bom</artifactId>
    <version>1.1.3.RELEASE</version>
    <relativePath />
</parent>
  • 1
    I leave it to others to answer. The idea is very sound. You could start with a parent POM with dependencyManagement, and a jar for the DAOs like Person. A very basic library. And so on. Of course no cyclic dependencies. – Joop Eggen Sep 20 '16 at 13:47
19

Is it possible ?

Yes certainly. I have in the past structure a few projects like this, here some bits I hope will get you started.

There are two main features of Maven you will use to weave things together:

Divide and conquer

You will need to split your projects in multiple independent projects. Here by independent I mean that all references to code outside the project is done through dependencies in Maven and not directly merging the source tree.

Depending on the state of your source tree this could represent a lot of work. That said you are not doing it to shoehorn to Maven but rather as a mean to structure and sanitize your code base. Think of it as your toolshed, much easier to find things here:

Nice toolshed

than here:

Not-so-nice toolshed

Maven relies heavily on convention so the better organized your stuff is the more Maven can help you. That said, It may require you to re-organize to better fit it's own convention and if I have to give one piece of advice here is that it's MUCH easier to change your stuff to fit Maven's conventions than it is to try and configure Maven to understand your convention.

If these projects could be usable outside the main application they could live as truly independent libraries and included though maven dependencies. They should live in their own repository (not in the application source tree) and should not depend on any part of the main application.

Core parts of your application, once split in projects can be put together as modules. Typically you will have them placed as sub-folder of the main source folder of your app.

Also your parent POM for your app will contain the module declaration. You will also place in there all the common dependencies for your app as well as declare most of the build plugins and their configuration. In here also I stronly reccomend you place a group of properties for things such as the version of the application which you can reuse in the modules. Much easier to manage when everything have the same version and having the version in one place makes this just work.

Tooling

If you are a team larger than 1 I would also strongly reccomend that you install a repository for your Maven dependencies. Look at Artifactory, Nexus or Archiva. You can configure the POM file to install to these directly so once running it should not be much of an overhead but will save your team a lot of time resolving the dependencies with the correct jar in the correct place.

On the subject of tooling the next logical step here is a continuous integration system (Jenkins, there are many more). It will handle building the source running the tests and pushing to the artifactory, with all this in place all you have to do is work the code and the rest just works.

Since you are packaging your app as a war maven can handle building the war and place all the dependencies in their proper places without having to merge jar files or other similar work around, so no worries there.

Example

I could go on much longer here but nothing beats a good example. Look on github for projects of similar magnitude and see how they built their pom files and folder hierarchies. Look at more than one, some will fit your setup better than others, none really incarnate the truth but you should find enough to fuel your thoughts on how to get it done.

Take Jenkins for example:

You can see their parent POM is quite extensive.

They do use modules as you can see in this section:

<modules>
    <module>core</module>
    <module>war</module>
    <module>test</module>
    <module>cli</module>
</modules>

And each module correspond a sub-folder with the same name that also contains a POM. You could nest as many as you want like this, though do keep it within sanity levels ;).

Start Small

If you have never used Maven I would suggest however you do not start with modules right away. Take it slow, start with, say one of the simpler libraries you may have and make it a maven project. Then make your main application a simple maven project. Once that work, start adding simple dependencies, then split your first module and so on.

Maven is a great tool but it can also be a super pain in the neck especially when things are not going your way. Starting with the whole whammy on your first go is a recipee for disaster (was for me!).

If things are a bit weird you can always use mvn help:effective-pom command to see what Maven actually understood.

plugins

From your comment I understand better what you want to acheive. In this case I would go for plugins approach. Create a project that exposes the API of extention points where you want to isolate the work. Then you can use this as a dependency in a new project that will implement it. In your main application just add the proper dependencies for these implementations (not using maven modules this time) and you should be good to go. Eventually the main application project will carry nearly no source code everything being done in external projects and loaded through dependencies.

You will need to re-deploy the whole application however with this approach, regardless if the core changed or not as the war is statically built from the dependencies, changing one of them implies rebuilding the whole thing. It sounds worst than it actually is, In effect only the new changes will actually get built, the rest will basically be a copy of the previous jar(s). But since everything is in the war file it will need to be re-built, and the server will need to be stopped and restarted.

If you need to go further things get a tad bit more complicated, though not impossible. I would reccomend you look into OSGI, Apache Felix could get you started, though there are other implementations as well. This will allow you to take the external jar and make them into proper plugins. You will gain a lot more control on the runtime lifecycle of the components opening the door to dynamic reloads and updates. It will however require major changes to your core so again, probably not a good starting point. However once you have a project that is well separated and have all the parts isolated the way you want, that could be a natural next step if starting and stopping the application on update is a major problem.

The basic difference between Modules and dependencies is this:

  • Modules will live in the same source tree as the main application, as sub-folders ideally.
  • Dependencies can be anywhere.

You can find the bible here.

Hope this helps, good luck.

  • Actually bundling modules through maven instead of the source-tree cleared up a lot of questions I had. Can you please tell me about deployment of such a project. One of the other reasons we are considering is so that developers can work on their required module and make the changes realtime. One thing we wish to avoid is to stop the application server and start again, other than for core module. As 2 modules I can think of will contain code which changes often. We use tomcat as application server, loadbalanced by Apache. Thank you. – We are Borg Sep 20 '16 at 17:10
  • Maven modules often sit in the same source tree as the main application. Using maven modules outside the source tree actually is more complicated than it`s really worth. If you do host the projects outside the source tree then go for normal independent projects and use normal dependencies. – Newtopian Sep 20 '16 at 17:51
  • I think we will go for adding parts of our project directly as Maven dependencies. This way, we can directly work on parts of project. Just one question I had, if we add one of the sub-projects as a dependency in POM.xml, say version 2.0.0, and then with some changes, we push a 2.0.1 of the module to sonatype, how can we directly tell the core-module to go for 2.0.1, will just changing the POM.xml inside ROOT.war and deleting ROOT directory be sufficient. Main intention is not to stop the server. Thank you. – We are Borg Sep 21 '16 at 7:08
  • pom.xml have no bearing at all once the war has been created, that is Tomcat (or whatever container you use) does not use this file. The file is used by Maven to create a new war file, which in turn you will have to deploy to the server. So the cycle is work on the code, create a jar file, update the version in the war's POM, create a war file, update the server with the new war file. Some server will support hot re-deploy though generally that would imply turning off the application for a few seconds. – Newtopian Sep 21 '16 at 14:38

protected by gnat Nov 16 '18 at 21:41

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.