maven multi module project repeated build issue - maven

I have created a multi module maven project as below
- root module(parent module. Building this will build the below children modules)
dao
service
web
dao and service modules creates the jar file. web module creates the final war file to be deployed. service module has the dependency of dao module. web module has the dependency of service module.
Whenever I implement new functionality, I have to modify all the modules from dao to web. I have a maven jetty plugin configured in web module. To test any new implemented functionality in UI I end up building dao and service modules always. Are there anyway to avoid this process and reflect the changes from dao and service modules whenever I run mvn jetty:run in web module?

No, there is no way to da that, and this is the intended behavior.
If you have these 3 projects, this means the have their own lifecycle. If not, the best is to have only one project.
However, you could avoid mentioning a version number in the project, and rely on a parent version number (your root module could also be the parent).
So, you could rebuild everything from the multi-module project.
However, I don't really see the point.
Why do you have 3 projects ?

Related

Spring Boot Multi Module and Fat jar with Shared Features

Experts,
I need some expert advice on how to approach the below use case in spring boot.
I need to have a maven multi-module approach to my project.
I need to have a single jar as output of the final build process.
There are to be common modules for controllers, data access and other functionality
Other modules are to be created based on functionality domain for eg a module for Payroll, a module for Admin etc etc.
Each domain functional module will then have their own controllers extending the common controller, exception handler and so on.
Each module will also have its own set of thyme leaf pages.
The reason for following such an approach is we have development in phases and we will be rolling out based on functional modules.
Here are the issues that I can sense using this approach.
Where do I add the spring web dependency? If I add to the parent pom - it gets replicated across the children and there will be port conflict issues as each module loads. the same issue will also be there the moment I add it to two child modules.
How do I build the fat jar which has all the jars from all modules and works as the final deployment?
All the text that I read i can't see anything even close to what I am trying to achieve.
AD1. They will not unless you are trying to setup independent application context in each module. Of course you can do that(it might be complicated but I believe it's achievable), but for me it's an overkill. Personally I think it's better to have one application context and rely on scanning components that are present in classpath.
AD2. The structure in maven might be a little bit complicated and overwhelming at first glance but it makes sense. Here's how I see it:
Create a parent module that will aggregate each module in project and will declare library/plugin dependencies for submodules.
Create 1-N shared submodules that will be used in other modules. With come common logic, utils, etc.
Create 1-N submodules that will be handling your business logic
Create an application submodule that creates application context and loads configuration and components from classpath
Create a submodule that will be responsible for packaging process, either to war, jar, uber-jar or whatever else you desire. Maven jar plugin should do that for you. For executable uber-jar, you have dedicated tool from spring.
Now you can choose three ways(these ways I know) of loading your modules.
1. Include some modules in maven build based on the build configuration via maven profiles and let spring IoC container load all the components he finds in the classpath
2. Include all of the modules in maven build and load them depending on spring active profiles - you can think about it as of feature flag. You annotate your components or configuration class with #Profile("XYZ") telling spring IoC container whether to instantiate component or not. You will need (most flexible solution) to provide a property file which tells spring which profiles are active and thus which modules should be loaded
3. Mix of these two above.
Solution 1 pros:
build is faster (modules that are not included will be skipped during build)
final build file is light (modules that are not included are... not included ;))
nobody can run module that is not present
Solution 1 contras:
project descriptor in maven may explode as you might have many different profiles
Solution 2 pros:
it's fairly easy and fun to maintain modules from code
less mess in project descriptor
Solution 2 contras:
somebody can run module that is not intended to be run as it's present in classpath, but just excluded during runtime via spring active profiles
final build file might be overweight - unused code is still present in code
build might take longer - unused code will be compiled
Summary:
It's not easy to build well structured project from scratch. It's much more easier to create a monolith and then split it into modules. It's because if you already created a project, you've probably already identified all the domains and relations between them.
Over past 8 years of using maven, I honestly and strongly recommend using gradle as it's far more flexible than maven. Maven is really great tool, but when it comes to weird customization it often fails as it's build capabilities rely on plugins. You can't write a piece of code on the fly to perform some custom build behaviour while buidling your project, you must have a dedicated plugin for doing that. If such plugin exists it's fine, if it's not you will probably end up writing your own and handling its shipment, so anyone in your company can easily perform project build.
I hope it helps. Have fun ;)

How to create a new microservice spring?

I'm using Intellij IDE Ultimate and I create a Project with spring inicializer. The problem is... now I need create more microservices (Spring Boot) but idk how to do this in IDE. I the end I need 3 microservices. Have a terminal command to create a new microservice inside my project? Or a way in the IDE to do this.
What you need to do is creating several modules (normally Maven modules), each of them is a SpringBoot application with its own application context and its own configuration, directories structure, etc.
IntelliJ has a concept of Module which matches very well the Maven module concept.
If you go to File, Project Structure, Project Settings, Modules you can see a very nice view of the current modules (in your case it should be only one). You can add or remove modules there. (Also by just clicking File-New Module, but the Project Structure View is more useful).
If you decide going the Maven way, you can also create your structure in disk and its POMs and import maven project in IntelliJ.
In any case, keep in mind that you will like to deploy every microservice as a separate and autonomous deployable unit.

Liferay7 service builder dependency

I have created a service builder project (Gradle type) in Liferay7 called register-user. There is another service builder project called register-organization. I have a situation where one of the service builders depends upon other. However, i am not able to figure out where to put the dependency of one into another. Is there is any way to do that?
With each servicebuilder project you create from the template, you get two projects, e.g. register-user-api and register-user-service. The -service project depends on the -api project and has the dependency noted in its build.gradle. Look it up and use exactly the same notation to make any other project depend on register-user-api.
The situation changes if both projects do not live in the same workspace: In that case you'll need your own repository (e.g. proxy for Maven Central) where you publish your own modules. Then you can just declare a standard dependency for your modules.

When to use maven multi module project

I was going to couple of blogs to get the basics of maven, in the mean time I was confused when I can use the multi module project. It will be great if the answer includes example.
The main idea is that you have small modules that are dependent on each other and can be grouped together. Its not necessary that all sub-modules in a multi-module project be dependent on every other sub-module.
Lets consider you have multiple modules for an application (e.g a social networking application) that belong together. These modules can range from smaller modules like a client consumer module or a server module that will serve requests initiated by the client module, an ejb module that will hold your beans that are used by both the server and the client module and a deploy-able web module that would comprise of your front-end application etc.
This is usually handled via a multi-module build which means all modules have the same version number, are bound together under a similar platform (a social networking application in our example) but can be accessed and used by other separately.
Please check How to assemble multimodule maven project into one WAR? to know how to package a multi module project in a war file. also, you can check maven official site on Introduction to pom file

how to access some new java classes added to the existing jar from gwt project when we run with Maven

I am facing below issue when I am running maven for gwt project.
in my project we have "A" project created by using gwt frame work.
"B" project is a java project and we need to access B project classes in "A" project server side.so created a jar for B project and added in A project build path.
Now I need to add some new classes in B project and that new classes should access from "A" project client side.
We can able to add new classes in B project and after running maven for B-project, we are able to see new classes in B-project jar.
But when I run maven for Project A it shows an error like "did you forget to inherit a required module?".
Note: same test projects I have created and can able to access B-project new classes in A-project client side code. But when I am running with Maven it is unable inheriting these new classes.
Kindly advise me how to solve this issue.
Generally you need to compile your code into javascript in order to make it accessible from the client side (if we aren't considering requestfactory proxies, web services etc. here). If your code is located outside the GWT module it simply doesn't exist for client side. Practically this means that you need to extract the client side accessible classes from the B module and put it into A\shared folder for example. Also don't forget to place <source path="shared" /> into your A gwt.xml descriptor. The drawback of this refactoring of course is that you're allowed to use only "JRE emulated" classes in your shared code.
Another solution would be a creation of a gwt module inside your B project and inheriting it in A project.

Resources