Sunday, 7 April 2013

How do I add a project as a dependency of another project and why would I do so? (Maven)

When working in a Java EE distributed system many times we have to manage the dependencies of each of our nodes. Our system will be full of other projects, representing different aspects of the system.


In this post I want to explain how to include a project as a dependency of another project by using an example scenario that is very common in real life: "Sharing the domain model between nodes".

As we know the domain model is the representation of the data that our system works with. To avoid inconsistencies it is a good practice, that each of the projects in our system that are supposed to interact with the domain model do so in a safe way. By interacting safely, we mean look at the domain model as a provided service that the projects use, but without the possibility of corrupting it.

One of the most common ways of achieving our goal would be, to create the domain model, as a separate project, and reference it there where it is needed. Doing this none of the distributed projects of our system will have to be responsible for the domain model, their only responsibility will be to keep the dependency updated, to make sure that they are using the very latest version.


In the following image we can see an example of what could perfectly be a class, in the domain model of a distributed system(Just a trivial example):



This is the project that contains the model and if we want to make sure that it can be use as a dependency in another project, we need to make sure it is packed in a .jar (note the content of the packaging tag in the next image).



When this program is built using the mvn clean install command, it will generate a .jar file that will be stored in the local maven repository(~/.m2). If the build process is successful we should see a message similar to this in our console(Note the message that says that the .jar was installed in the repo):


 A very important thing to understand about this process, is that future versions of this project will need to be increased and also will not have the SNAPSHOT postfix when deployed as stable version. If this process is always done manually by the developer, it possible to make mistakes and that is why in real live, many companies use special tools for building and deploying such as Jenkins and Hudson. The set of tasks and tools that allows distributed software built and deployed automatically in a safe way, is known as Continuous Integration.


Now that we have built and deployed(In this example we just deployed it in the local maven repo) our new domain model, we can reference it in another project.
In this example I will use the model in a project that represents a data access layer for a distributed system, to do so, we will need to add the dependency to the correct version of the model inside the pom.xml file:





Once we build our project we will see that the .jar that contains the model is in the class path and we can use it with no problem in this project:



 When a change is done on those projects on which other projects depend, in order to avoid versions miss matches and inconsistencies, it is a good practice to update all the versions in the dependent projects, re-build and re-deploy.

Now that we know how to add the domain model as a dependency we can add it to other projects that are part of our system(e.g a web app).

Just as a little appendix and even if is not directly related to the post, there is an excellent text about why the Data Transfer Object pattern is no longer needed in JEE in the book: Enterprise JEE Patterns. Rethinking best practices(page 273).  There is a very interesting explanation of why DTO's became superfluous when the JPA entities were introduced. 

No comments:

Post a Comment