If we have a multiple module project,
Parent Project
Model Module
Services Module
Web Module
And the parent project pom.xml, lists the 3 modules in <modules>...
And then Services pom.xml has a dependency on Model, and Web Module pom.xml has a dependency on Services...what does this mean?
Does it mean I can't reference in my Web Module, any of the Model classes?
i.e. does the dependency chain in Maven impact this type of scoping?
So I cant in appContext.xml in my web module control any of the injection of beans outside of Services/Web Module?
Many thanks (sorry for noob question)
i
Your question is not very clear but what I could gather is that you want to ask whether in your web module you can access your model class. Definitely you can because of transitive nature of your dependencies. Since Service module depends on Model and Web model depends on Service, you can definitely access Model classes in Web module. You can understand this better if you run the mvn dependency:tree command on your Web module. The Model would show up in the dependency tree or if you are using Eclipse Maven plugin you can view the Effective dependecy in a tree structure which is visually better to understand.
Related
Let's say I have a maven project which has some maven modules inside.
My main module depends on the other modules, so when I compile the main module they should be compiled together.
The question is, how to add these modules as dependencies to the main module?
I know if I have a custom lib that I want to use with maven, let's say a utilities project, I have to compile the jar of the project, do a mvn install:install-file on it to install it on the local repository and then add it to the pom.xml.
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module? Because if it should be done like this, there will be a lot of work to do when changing code on the other modules.
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
The question is, how to add these modules as dependencies to the main module?
The same way you add any other dependency to your maven project. By adding group id, artifact id and version to <dependency> element
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module?
If your main module depends on some module A then only the pom of the main module should contain dependency declaration towards module A. You do that for all the dependencies of your module.
I don't know what you mean by "a lot of work when changing the code on other modules". Maven has nothing to do with code changes, it just builds the projects whatever they look like at the given moment...
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
Any project that you invoke mvn install on gets built and it's jar copied to local repository. That's all you need to do to get the jar into the repo. This will also put all the dependent jars, if available, into the local repo.
As for best practices for multi module projects:
If your parent project (the one that has modules inside) has <modules> section that lists the modules of your application, and modules are in subdirectories of your parent project, then you simply mvn install (or whatever you want to do) the parent project and that will cause all the modules to be built in order defined by declared dependencies between them. That means that if your main module has dependency on module A, then module A will be built before the main module. This way you can build and install all your modules with one command. On the other hand this approach makes more tight coupling between modules which is not desired in some cases, so it depends on your use case whether it is a good approach or not.
I have an interesting concern. I am used to multi-module Maven projects. Now I am investigating how to do the same but also using Jigsaw. Am right that every single Maven Module can have only one Jigsaw module? In IDE I can't create the second one inside the same Maven module.
So, is there any convention or workaround so far how to combine both sides of modules?
When Project Jigsaw developed the Java Platform Module System it decided that a modular JAR is a regular JAR with a module descriptor, a module-info.class, in its root folder. That means a JAR can only define a single module. There have been request for multi-module JARs, but the feature was deferred to a future release.
That one-to-one relationship between JPMS modules and JARs taken together with Maven's one-to-one relationship between Maven modules and JARs leads to the fact that a Maven module can only contain a single JPMS module.
(I created a module system tutorial and a corresponding demo project that uses a multi-module Maven build to create modules - maybe they're helpful to you.)
Here is the simple situation breakdown and I'd like to know if I'm doing this optimally or if there is a better convention. I have created a dummy project just for learning purposes.
I have created a multi module Maven project. Simply the parent POM, with two sibling child POMS, one being a service layer, and the other being a web layer.
The end result goal is to have a fully functioning WAR in the Web project's target folder, that I can simply deploy into a Tomcat.
Here is where I am not clear:
- Both the Service project, and the Web project need to use Spring. The Service project needs to use Spring simply for it's dependency injection purpose. I need to take a simple Dog class, and auto-inject it into the DogService object. That's all working fine.
- Then I need to auto-inject a DogService object into a Dog controller. The Dog controller exists within the Web project in the multi module structure. This is also working fine, because I have declared a dependency in the Web project for the Service project, therefore all Service JARs are included in the final built WAR, from the web project.
1) Is there a way to simply declare a Spring dependency for both child projects without having to declare the dependencies in each child POM.xml? I just want to make sure I'm not duplicating resources. I believe the way to do this is just to declare the dependency in the Parent POM.xml.
2) If I do #1 above ^, is this the optimal way of creating the project? In essence, the WEB module is the one that contains all the final jars, and in essence it's almost as if the SERVICE project doesn't even exist in Tomcat. As far as Tomcat 'knows', all there is, is a bunch of JAR files containing classes, some of them having been written in my WEB module, and some of them having been written in the SERVICE module, all of which is irrelevant to the production/Tomcat environment. True or false?
Thanks!
Is there a way to simply declare a Spring dependency for both child projects without having to declare the dependencies in each child POM.xml? I just want to make sure I'm not duplicating resources. I believe the way to do this is just to declare the dependency in the Parent POM.xml.
Maven is quite intelligent about dependency management and will not "duplicate" resources--it caches each dependency once* and manages the classpath so that all of the projects that you work with share the same jars. In general, declare dependencies in the modules where they're needed; don't clutter up modules or especially parents with random pieces just to avoid occasionally re-specifying a dependency. This is like hauling your boat trailer on your daily commute because you occasionally go to the lake.
Keep in mind that dependencies are transitive, so that if service-module depends on spring-web (does it really, or are you spamming dependencies?), if web-module depends on service-module it will pull in the dependency as well without having to repeat yourself.
If I do #1 above ^, is this the optimal way of creating the project?
No, it isn't. Be minimalist about your dependencies: If you need it, include it, but don't add dependencies "defensively". This will just bloat your deployment and slow down builds, along with adding opportunities for problems like version mismatches.
As far as Tomcat 'knows', all there is, is a bunch of JAR files containing classes, some of them having been written in my WEB module, and some of them having been written in the SERVICE module, all of which is irrelevant to the production/Tomcat environment. True or false?
Mostly false. In a war, your top-level project (web-module) has its classes directly in the archive, and dependencies are embedded as jar file inside it. Tomcat does not distinguish between service-module and your Spring and other dependencies, however.
Better still would be using Spring Boot's standalone jar and embedded container features--Boot will take care of packaging up the jars you need into a single runnable file that doesn't need external support.
*Release dependencies only, but snapshots aren't relevant here.
I have two projects that contain reusable code for many different services and web apps, such as CommonService and CommonWeb.
I want all my service projects to reuse as much pom configuration as possible from the common service, but I still want to leverage the spring boot starter poms in the common projects to help set them up. What would be the best way to organize the pom hierarchy?
CommonService and CommonWeb both have code, dependencies, and plugins like the AspectJ compiler. Would my AppService add CommonService as a dependency, or as a parent?
We solved it by having common parent that is inherited from Spring Boot parent. This common parent would be parent for each of projects. This was particularly handy for micro-services architecture.
If you have different types of projects, e.g. HTTP vs messaging service, you can have inheritance hierarchy of POM parents where root is always Spring Boot parent.
If you don't like idea of having inheritance hierarchy of parent POMs, I suggest to analyze Spring Boot project, how they organize POMs. It is very clever, but may be overkill if you don't have a lot of various types of services/projects.
Of course these POMs need to be properly versioned and deployed to some artifact repository as standalone artifacts.
Since a maven parent POM must be in pom packaging.
You should have a CommonParent maven project besides your CommonService and CommonWeb projects like this:
common (maven aggregate project)
+- common-service (module with `jar` packaging)
+- common-web (module with `jar` packaging)
\- common-parent (module with `pom` packaging,
and dependent on common-service, common-web)
Then you just have all your projects' POM be a child of your common-parent.
Furthermore, you should write your own AutoConfiguration classes and use the #ConfigurationProperites encapsulation provided by Spring Boot to construct your own application properties. So that a downstream project can control over your common configuration easily by settings property like common.web.feature1.enabled = false.
I try to make a JavaEE application with 2 and more Spring MVC modules. Before I had WebSuite module, that have Web and DB modules
<modules>
<module>../UBDB</module>
<module>../UBWeb</module>
</modules>
In the DB module are all classes that work with database; in the web module - Spring MVC for views.
But now I need to re-organize my project. I need Maven managed modules, that will consist of different business logic. For example: I need one module that will have controllers and views to manage accounts, another module to create orders, another module for blog etc. (something like CMS). All of these modules need to be on Spring MVC.
But how do I need organize my pom.xml files to make it?
For a webapp, we always loose our time with maven module to think we have a nice separation... that's useless.
Create an account-parent with
Account model
used by Account dao
used by Account service
used by Account controller
Do the same for all the group you wanna do.
Then create a single module app : MyWebApp. It contains just config, properties and add all the controllers in runtime.
You will loose your time while releasing modules, updating dependencies, ...
I worked this way untill last year.
So, sorry for late answer, but I found solution.
I have one module suite - that I use to get all modules in my project
<modules>
<module>../news</module>
<module>../blog</module>
<module>../suite</module>
</modules>
Also it have <packaging>pom</packaging> property
Description news and blog are quite similar
We can package it like jar files.
So, as I sad, I whanted to have some CMS system. How it works. I copy all nessesary modules to some directory. For example I will create site with news and blog module. So I copy there suite module, news and blog module(news and blog module are Spring MVC apps. Suite just pom.xml file). Then I create new directory (site module). In pom.xml of it I set
<packaging>war</packaging>
then in suite module I ad line for it.
<module>../site</module>
So I have 3 SpringMVc applications. 2 of them (news, blog are my modules, that I can set to different projects. Site - new module. It will be deploeed like Jar file This module different for different projects) and suite just to get all modules together.
And then mvn clean package.
Hope It will help for someone