My project depends on an external library, which consists of a number of maven projects.
Do I have to define each of the projects in the library to be a module in my project's parent pom.xml? Is there a way to define the library as a whole in my project without individually listing all the projects?
My project directly depends on only one project in the library, but that project depends on other projects in the library.
Do I need to define all the projects in the library in my project's dependencies?
Ideally, in parent pom you define modules i.e, external libraries which you want to build. When you build the parent pom, it will build all modules which are defined in parent pom. And further, modules will build other dependencies/modules.
You need a composite pom -- a pom which just declares a bunch of dependencies. You depend on it, and transitively, you get its dependencies.
See this discussion for more information.
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'm developing library with Maven system, which is published in the Nexus repository.
In the nexus (and the maven build as well), the project produces the final jar named <projectName>-<version>.jar - this is exactly what I want.
Now, I decided to split the library into maven modules and therefore top level pom.xml have <packaging>pom</packaging>. The build also do not produce final <projectName>-<version>.jar, instead it produces <moduleName>-<version>.jar for each module.
What I want to achieve is to have the project split into modules and be able to produce final <projectName>-<version>.jar containing defined modules. Is this possible?
Is it possible to solve this issue migrating to the Gradle?
When you decided to split the library into multi modules it means that you decided to build them independently. So it's expected that each module creates it's own <moduleName>-<version>.jar.
Now when you use the created modules as dependencies for the bigger module with scope of compile maven would automatically add them to lib of the project.
So in your case you don't need to change packaging to pom and just add the modules as dependency in the pom.xml file and let maven to create the final jar for you.
Also if you want use pom packaging there is a good question here which might help you.
I have a project which has 3 pom files: parent file (very basic one, just declares its children), main pom for building project itself and a pom file for generating swagger client library. The client artifact is getting downloaded into our Nexus.
The problem is that when I want to use a client library in another project as a dependency it also requires a parent artifact. I don't want to download it into Nexus since it's so basic and will only flood the repository. I've tried packing some kind of an uber-jar, but it doesn't work for me - jar is huge and contains all dependencies, yet it still needs parent artifact. Are there any workarounds?
While I generally would not care about having an additional Parent POM in the repository (our repository contains 2000 different self-created artifacts in various versions, it is not "flooded"), you can have a look at the
https://www.mojohaus.org/flatten-maven-plugin/
which allows you to make your pom smaller, and includes the possibility to get away without a Parent POM.
With maven I can create a parent pom.xml and extends it everywhere. Also in parent pom I can define some general properties like library version and other properties which are wanted to share across several imdepeneded projects. How to do this with sbt if projects are different and they do not build from one root project/folder?
Important
The question is not about multi project build!
Not tested, but should work:
Create a normal SBT project, define your desired settings, etc. there. Let's say it's in the path ~/parent.
Note that the project folder of an SBT project is itself a project.
You can depend on external projects from file system or VCS in SBT. In the builds where you want to reuse parent project, create project/project/Build.scala (or project/build.sbt) if it doesn't exist yet, define the project as usual and and add a dependency on ProjectRef(file("~/parent"), "project").
My project has different modules.
Each module has a pom.xml which specifies jar packaging.
Each pom refers to common parent.
In the parent module there is also a pom.xml which includes all the modules.
When I tried to package using the pom.xml of the parent module, it shows the error - "Packaging jar is invalid Aggregator project need pom as packaging".
What can I do to make an executable jar of the application from maven?
To make things short: if your parent-aggregator project don't contains source code (and it's a good practice), just add this to your parent pom.xml:
<packaging>pom</packaging>
If the parent project contains source code, I strongly suggest you to:
move this code in a new module (let's call it commons)
make commons a child module of your parent project
add the commons module as a dependency of all other modules requiring it (maybe all of them)
add <packaging>pom</packaging> in the parent pom.xml
Maven requires the parent to be of packaging pom.
You can make a pom project behave as if it were a jar project, by including a bunch of plugin executions and attaching them to their subsequent lifecycle phase. It's not a happy road. On the contrary, the following is.
From an object oriented standpoint, what is it that you want? You have one object that is made up out of a bunch of other objects, right? In other words composition, as opposed to inheritance.
Your final delivery is made up out of the other (jar) projects, i.e. the other projects are dependencies of the final delivery project. You will define the other projects each as dependency so that whomever uses your final delivery knows what (transitive) dependencies to get. Alternatively the final delivery jar could be packaged up as "uber-jar" and thus contain all its dependencies. That all really depends on how the final delivery is to be used.
At the same time the following two aspects (may) still exist:
The parent project (which is different than the final delivery project, in fact it may be the parent of the final delivery project also) defines commonalities between its subsequent children, as is what you should expect from inheritance. A child is any project that refers to the parent through the parent configuration in its POM.
A project that defines modules that are to be easily built in one go. Modules are projects that are referred by use of modules.module. This is typically (I guess >99%) done in the parent project, but not necessarily. You could put it in the final delivery project also (without affecting inheritance, because that is thus a different beast), but it's atypical and I would not go there.