Can you import a profile into a maven pom.xml? - maven

A RESTful web service project that I'm working on needs to be deployed to a very unique environment (that requires a lot of custom configuration) in addition to the typical deployment environment and the integration test environment.
I have created a build profile for the unique environment, but the definition is REALLY long, full of Ant Tasks, etc. and I'd like to put it in its own file and import it into the pom.xml just to keep things clean.
Is that possible?

The only option with the latest version of Maven at the moment (3.0.5) is to put your profile into a parent POM and inherit from the children.
One day when it is finished, POM Mixins would help but this feature is not yet finished.

Related

Best approach to build and run with env specific values - Spring and K8S

Building a Spring based project deployed in kubernetes using Spring Cloud Kubernetes library with Kubernetes. The build is using maven and GIT CI/CD. Exploring the build process to package environment specific files and the runtime to pick up env specific files during execution. In traditional deployment, used to use maven profiles to build env specific libraries and configurations. Now spring has profile and maven has its profile. Besides, some of the designs includes files/configurations for all env included in the build and only a activated profile will use the correct configuration. Is it advisable to include all configurations in the package?
Is there a best approach on how these two work in handling env specific files or any other optimized approach to handle this?
I'm afraid that:
In traditional deployment, used to use maven profiles to build env specific libraries and configurations
was never a case for maven profiles, if you take a look at official guide you may find following:
Apache Maven goes to great lengths to ensure that builds are portable. Among other things, this means allowing build configuration inside the POM, avoiding all filesystem references (in inheritance, dependencies, and other places), and leaning much more heavily on the local repository to store the metadata needed to make this possible.
However, sometimes portability is not entirely possible. Under certain conditions, plugins may need to be configured with local filesystem paths. Under other circumstances, a slightly different dependency set will be required, and the project's artifact name may need to be adjusted slightly. And at still other times, you may even need to include a whole plugin in the build lifecycle depending on the detected build environment.
To address these circumstances, Maven supports build profiles.
So, maven profiles was designed to support codebase portability across build environments, but not to build artifacts for particular environment.
"Traditional" way to inject environment-specific settings into j2ee-application was to setup those settings via JNDI, i.e. j2ee-container was providing a configuration via JNDI and our application was consuming that configuration via JNDI. In case of spring/k8s/etc the main idea should remain the same: application knows how to retrieve configuration (system properties, environment variables, configuration server, service discovery, etc) and environment provides that configuration.

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 ;)

Bamboo task to update properties file before maven build

I am using spring-boot and would like to update the application.properties file in the /src/main/resources folder as a task within a manual build plan. As the service can be installed on premise at the customer, I want to build the jar for each customer, where I can provide variables (e.g. spring.data.mongodb.* properties) to be injected/overridden before the maven build.
I found the inject plugin, but this adds a prefix before the variables, which in this case wont work as the DB connection is done automatically with spring.
Is there another plugin I didn't find which could do the trick, or is there an easy way to script something like this (please provide an example as I am not very familiar with shell scripts)?

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.

How to combine 3 standalone applications on java and run parallely with maven in spring

How to combine 3 standalone applications on java and run parallely with maven in spring.
The three othe standalone applications run on different Db's and I want to make use of these three in my main Standalone app.
What are the required maven settings i need to follow and what are the best spring components i used.
Any kind of answer is appresiable.
Thanks in Advance.
About Maven.
I recomend you to use a Repository Manager (Nexus, Artifactory...). In that repository, you can upload manually your aplications as a jar (I assumed that these three app are not build with Maven, but it could be interesant to migrate them, you should evaluate that).
You have to configure your new app pom.xml and settings.xml to get access to this repository. And then, you can add these dependencies in your new app pom.xml. After that, you can use your applications classes in your new app.
About Spring
Spring Framework, has a lot of things that could help you in your development (like dependency injection, jdbcTemplate and a large etc)
I really recommend you to read the documentation (with the index you can get an idea), and evaluate what things could help you.

Resources