In my project, we are given a sample project structure to be followed and I am very new to multi-module projects.
We have a parent project and 4 sub-projects that have that as parent.
And in the parent project, only 3 out of those 4 are configured as modules.
What's the difference/significance in having a project as a child but not as a module to the parent project?
Other than dependency management, what do we achieve by using multi-module project hierarchy?
1) The "parent-child" relationship helps to manage dependencies. Say in your company(or project), you have some common libs that nearly all projects(or sub-projects) need to depend on, or you have a standard build configuration. You'd better put these common dependencies and build config in your parent pom, so that all children can inherit from parent. This is quite like inheritance in OOP.
2)If a project can be divided into many modules, and these modules highly couple with each other. Which means in most cases they are modified and build together, and none of them can be taken apart as a library for other projects. Then you can declare them as modules of a multi-module maven project.
But personally, I don't quite recommend multi-module maven project since it not flexible and more complex to build and to work with IDE,CI or other tools.
Related
I'm currently learning gitlab ci/cd and ran into a problem.
I am a java developer and I have written a multi-module maven project with microservice architecture.
At the root of the project, I have a BOM file in which the heir modules are declared and dependencies are declared in the dependencyManagment tag so that all microservices use the same versions of spring-cloud. Each module has its own repository. Logically, each module has its own database and pom refers to the parent (bom) to import dependency versions.
The question is that when writing gitlab pipelines, I get an error: Non-resolvable parent POM for (module name) ... It is logical that he has nowhere to get dependency versions, etc., but in this case, how to control the versions of the libraries of all modules or can maybe it's not needed at all?
Help me come up with a work plan.
At the moment the diagram looks like this:
root(bom) -> childModule(pom)
alsoRoot -> childModule(pom)
First, try this link for your error.
Also, for your project unless it represents a whole microservice, it is fine. But, it seems like you have implemented many microservices in one project. Every microservice should be an isolated project with its own dependencies and release process.
Each microservice project should be:
Independent
Autonomous
Easy to deploy individually
I have Maven project with multiple submodules. One of these submodules, let's say submodule X depends on all other submodules, as it is Maven Plugin that integrates everything else.
Now I want to use this Maven Plugin during verify stage in my parent POM to do real run of it over entire project (kind of eating own dogfood).
Unfortunatelly I'm getting error:
The projects in the reactor contain a cyclic reference
So how can I make such dogfood integration test for a Maven Plugin submodule?
I would review aggregation and inheritance: they are indeed two different concepts in Maven often used in combination but which can however be used in a complete separated manner as well.
In this case, your plugin submodule is certainly defined as a module in the aggregator pom (that is, it is a submodule). But I also presume the plugin submodule also has as parent pom the aggregator pom as well (that is, the aggregator pom is also the parent pom, which is a normal approach, but not always required).
Is the latter required? You could keep on having the multi-module/aggregator approach without necessarely having the aggregator as parent of the plugin submodule. As such, the plugin subModule would still be a module of the aggregator pom but it would not have as a parent the aggregator pom, decoupling it from it and as such breaking the cyclic dependencies.
Possible drawback: in the aggregator pom you were also defining common things (dependencies management, properties) required also in the plugin submodule. If the case, you would then need to duplicate/review these common settings only for the concerned submodule.
Small suggestion from my side. Cyclic means you have some transitive dependency in your modules. Can please check the dependency tree of your modules and resolve the circular dependency first.
Well here is an interesting experience i had since last couple of weeks structuring my maven multi module project.
When i decided to use maven for my build life cycle management i had couple of reason that i wished to choose maven.
a. Mostly development teams are divided so that each team can work on separate Module within the project like Team-A to work on User Management System, Team-B to work on Authorization System, Team-C to work on Document Management System...and so on. Each team has java developers, testers, UI experts etc.
So the maven Project structure should be such that each team can independently work on their respective modules. They must be able to code, compile, build, test, deploy their module without having to compile, test modules belonging to other teams.
And thus i came to conclusion that each development module of the maven multi-module project must represent a Functional Module
After some discussions on forums i found people suggesting me to follow layered approach were child modules must be layers like controller-layer,service-layer,dao-layer etc. I did not pay heed to this advice because this not solving my purpose of teams working on individual module. This way for large project the build and deployment time for each team during development increases which does impact the project time-lines. sometimes the build and deploy time is upto 30 minutes say if there are 10 to 11 modules in the project.
But i did pay heed to a suggestion that keeping DAO layer separate for each module is not a good idea as DAO is highly granular and reused by other modules. and so the dependency of one module on other would would any how become greater.
I found a solution to this problem by creating a common module and moving DAOs and DOMAIN to the common module which will be inherited as a dependency by each module. And this seems to be a more viable option. Now the Project Structure looks like this.
Now when i build the project and run the webapp on server, It complains 404, Resource Not Found. I found that this is because the WEB-INF/classes folder is missing, src/main/java is missing in web-app module. I searched and found couple of links that suggested it is Deployment Assembly issue in Eclipse. So i need to manually create these folders and add in the deployment assembly because maven does not do it.
But the bigger questions are
do i need to move the Controller classes like com.mycompany.usermgmtsys.controller.UserMgmtController etc.. to src/main/java Or maven should find the controllers from the module jars included as dependency in WEB-INF/lib.
I dont want to do this i.e. putting java file in web-app. i want all the controllers should be available to the web-app as dependency for example WEB-INF/lib/usermgmtsystem.jar. But then wouldnt the Tomcat be looking for controllers in classes folder.
I dont know what should i do ? Any suggestions would be appreciated.
Its the way the eclipse render maven based project. It generally creates two structure. One based on master pom (parent project) and others based on individual module pom. however doing changes in any structure will reflect in the other one. As a practice I do changes in individual module folder structures and is more easy to read too.
Personally I try to avoid multi-module projects as, if you're using the Maven Release Plugin, you are locked into releasing all your modules together.
While this may sound like a convenience the problem arises when you need to do bug fix release to one of the modules - you end up releasing all the modules, not just the module with the bug fix, incrementing their version even though they haven't changed.
You also take a hit if you're running CI with multi-module projects - you're build typically runs over all modules from you root pom but if you're working in a particular module, you end up taking the hit of building those that haven't changed, in effect losing some of the benefits that the modularization was meant to provide.
So, go with independent modules but, and this is the important bit, create a common 'dependency' pom used by each.
A 'dependency' pom is a pom that standardizes all the dependencies across your projects and is different in that those dependencies are specified in the dependencyManagement section rather than the dependencies section (it also sets up standard plugin config, etc). This allows your project poms to specify the dependency pom as their parent and then declare the dependencies they need minus the versions, which are picked up from the 'dependency' pom and thus standardized across your projects.
If you are still concerned about being able to built everything, this can be achieved with a simple batch-file.
This is a good question. There are many aspects that must be considered for a useful project layout. I'd like to try to answer one which you didn't mention. Is your app extensible by users? If it is, then consider creating a separate module for your public API layer (service interfaces, DTOs used by those services, and Exceptions thrown by the services).
In our app, we have several maven modules per functional area. The idea is that a group worked on a feature within just one functional area and this isolation kept them messing with sources being modified by another group. Each functional area is broken down further in maven sub-modules we call "api", "domain", and "service" - we don't lump services/controllers, domain, and exceptions into a single module. The api module contains those classes we want to expose to customers for their customizations. Our service layer is the implementation of those interfaces. Further, we do not allow one module's service to call another module's service as this would bypass our service orchestration layer where customer can attach extensions to our services. Using separate maven modules per functional area helps enforce this.
We have other modules (internal-api, web, adapter) but they don't really add to this topic.
I figured out the issue. Controllers are presentation-layer components. The dispatcher expects the presentation layer components in the WEB-INF/classes folder in the target rather than looking for it in the lib. I am not sure if this is valid only for maven based structuring in eclipse. So finally these are the changes i have made
a. Created a src/main/java source folder in web-app. It is not generated by default in web-app module.
b. Add packages and respective controllers in the src/main/java folder.
So the final structure that i have (i am not pasting exact eclipse snapshot, this is generalized view)
I'm just curious, what happens if there are used both inheritance and aggregation in the same maven application?
This is the application structure:
my-project-app
my-project-jar
my-project-war
Now, in app's pom.xml, I declare jar and war projects as modules, and in the same time the the poms from both modules declare the app pom as their parent. It is create some kind of redundancy here, isn't it?
What is the best solution for this case?
It's not redundant. They both do different things.
If you use aggregation (define <modules>), you just say which projects have to be built, and its package type is pom.
If you inherit (define <parent>), you'll inherit the parent pom's preferences.
See:
Inheritance and aggregation create a nice dynamic to control builds through a single, high-level POM. You will often see projects that are both parents and aggregators. For example, the entire maven core runs through a single base POM org.apache.maven:maven, so building the Maven project can be executed by a single command: mvn compile. However, although both POM projects, an aggregator project and a parent project are not one in the same and should not be confused. A POM project may be inherited from - but does not necessarily have - any modules that it aggregates. Conversely, a POM project may aggregate projects that do not inherit from it.
More infos here.
I've recently tried to work with NetBeans and I don't understand how it handles Maven multi-module projects.
My project has fairly complicated modules structure and when we're working on it (we mainly use IntelliJ community edition) we don't want to open all its modules (~50 modules) because it will take hours to load the project, instead we've created a 'workspace' module: a folder with pom.xml that has a packaging type pom and defines modules that I would like to load.
Lets say it defines modules A, B, C.
We have our main method (we don't use any type of container) in module A which is a low-level infrastructure module.
As a runtime dependency we need A, B, C. But A doesn't really depend on B, C, but rather B and C depend on A (in terms of Maven dependencies).
So we've created another module, lets call it runner, where we define all the dependencies. Our workspace pom.xml has module declaration of runner, so in order to run the project from IntelliJ, we use a 'classpath of module runner' while running method main in module A.
Now, How can I achieve the same affect with the latest Netbeans (7.1.2)?
I understand that question is kind of newbie's style, but I struggle with it a lot of time with no luck.
Just struggled with the same issue - from what's listed in the Netbeans wiki it seems that every module represents it's own Netbeans project and everything else would be expressed with project dependencies. See http://wiki.netbeans.org/MavenBestPractices
A project with modules is known as a multimodule, or aggregator project. Modules are projects that this POM lists, and are executed as a group. The Maven projects in NetBeans lists these modules as "Required Projects". So you will only get the required projects list populated for Maven projects with "pom" packaging that have modules defined.