I have a project which was designed using a custom archetype to build modules under parent project as follows -
Details - The archetype implements a <configuration> in the <build> phase with a <mainClass> let's say Generator that builds the classes under the pojos and service packages into a single target folder and hence enabling to create the final JAR for the user module as user-1.0.0.jar
There's some requirement in terms of separately exposing the pojos without the intervention of service code that has left me brainstorming -
Is there a way to modify the existing archetype or module structure to get two separate JARs for the packages pojos and service as user-pojos-1.0.0.jar and user-service-1.0.0.jar?
One way I possibly know is to move the code in two different module and building their jars but then for multiple existing modules under the parent and a thought over the same name modules under the parent, wouldn't be preferable.
Is there a way to modify the currently obtained user-1.0.0.jar created and separate out it into the two JARs required same as above?
Related
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 ;)
New to maven here...coming from the ant world
I need to create a client jar with a few files that will give my client the ability to write to my Db and make rest calls to my services.
These are mainly classes that wrap a Rest connection and db client.
Is it possible to produce this artifact as a side effect of my main maven project ?
Eg: main project produces a bundle when I run mvn package, but I'd like to produce the client jar by providing some other parameters....
What you need here is a multi-module maven project.
The structure goes like this:
-- Parent Module
----- Child 1 Module
----- Child 2 module
Here you can have all your code/files of your main app in child 1 module and put all the code/files for the client in the child 2 module.
The parent module is just an aggregator which produces an artifact of type pom. Whereas each of your child modules will produce individual jars.
You can then you the second jar in your client.
For a detailed understanding how multi-module project works, check this link.
The standard Maven way is "one project, one jar". This means that the cleanest way to achieve your goal is to set up a multi-module project where you have one module for your "normal" jar and one for your "client" jar. But there are other possibilities:
If you are talking about an ejb, you can use the maven-ejb-plugin and create a client artifact. Unfortunately, both artifacts then share the same pom (and, therefore, the same dependencies).
You can use the maven-assembly-plugin to assemble a set of files and deploy them as side artifact (same problem as in (1)).
You can use the maven-install-plugin and maven-deploy-plugin to install/deploy entirely different artifacts along with your main artifact. These artifacts need to be created before, e.g. by a custom maven plugin.
Zeppelin has an object ZeppelinContext, which can then be used to share state between languages and bind variables to angular and thus create cool user interfaces inside Zeppelin notebooks.
We have written numerous convenience methods to create things like drop down menus, buttons, UI stuff, from scala. These methods call ZeppelinContext. We wish to add these methods to an sbt project, so that we can package them in a jar, but it seems the Zeppelin project provides no artifact that contains ZeppelinContext (we have tried many).
Rather there only seems to exist two work arounds:
Build all of Zeppelin and add the resulting jar as an unmanaged jar (not nice).
Use duck typing (also really not nice).
Question: Is there a lesser known resolver / artifact id to get hold of this type?
The ZeppelinContext class is available on github.
From the related pom.xml file the Maven coordinates are:
<groupId>org.apache.zeppelin</groupId>
<artifactId>zeppelin-spark_2.10</artifactId>
Which leads to this Maven dependency on the Maven Central repository.
<dependency>
<groupId>org.apache.zeppelin</groupId>
<artifactId>zeppelin-spark_2.10</artifactId>
<version>0.6.1</version>
</dependency>
Effectively, the jar file contains the ZeppelinContext.class.
I Implemented two maven project each using spring MVC, Hibernate, Jax-RS service. they have separate configuration, database, controllers, models, services.
I need to combine both the project in such a way that one is work as parent and other should be its child and can access parent services.
If you want to share configuration among projects, you can use a parent pom.
If you want to combine two projects as subprojects of one larger one, you can use modules. Both concepts are described in
https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance_vs_Project_Aggregation
If you want to access classes from project in another project, add a dependency in the dependencies section of your pom.
We have a multi module maven project with the following layout
project
- common (contains DTOs and other utils)
- business (containes business services)
- presentation (presentation related)
Now, we have a webservice exposed from business module and we have to give a jar file with just service interface (from 'business' module) and DTOs (from 'common' module) to a dependent application which wants to consume the web service.
What is the best way to produce this artifact using maven?
Most elegant way I could find to solve the problem (without breaking Maven recommendation of one project, one artifact principle) is as below.
Create a maven module named web-services and use CXF-Maven plugin to generate the classes required for consuming the webservice. The artifact produced (jar) will have the required classes to be distributed to web service clients.
http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html
Removing the child module for webservice from parent project's POM xml should help (if i understood the question correctly).