Main Module
-pom.xml
Module1
jar dependency
Module2
jar dependency
I am new to Maven and am wondering what the best practice is for configuring the above setup.
We are upgrading our version of Alfresco (currently all of the above are compile via ANT) and for testing purposes and to make headway on the project, I initially just compiled Module1 and Module2 using their existing ant build scripts and then did a manual install into the Maven repository. I manually added the dependency in my Main Model pom.
Module1 and Module2 need to be compiled and rebuild every time we update Main Module. They are shared with other projects and can change frequently.
What I am working on at this point is the following:
In Main Module pom.xml, I am using maven-antrun-plugin to run the associated ant build scripts for Module1 and Module2. This is working fine and produces the two jar.
Now I would like to have my main module pom.xml file install the two jars into the maven repository.
My dependencies in my pom.xml have an issue when I update the project version since the pom.xml has not been run yet to install the two jars.
<dependency>
<groupId>ca.gc.hc.nhpd</groupId>
<artifactId>EformExtractor</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ca.gc.hc.nhpd</groupId>
<artifactId>SubmissionConsumer</artifactId>
<version>${project.version}</version>
</dependency>
Am I going about this incorrectly? It will work if I run the ant script and install manually and then add the correct version in the pom.xml dependency. We wish this to happen automatically though. We don’t want to have to do this manually for every build we do.
Perhaps you should structure this project with parent and child pom.xml files:
MainModule
|-- pom.xml
|-- ModuleA
| |--pom.xml
|-- ModuleB
|--pom.xml
The parent pom.xml would look something like the one in this example.
The pom.xml for ModuleA and ModuleB could run their Ant scripts, if necessary. Then you should be able to run mvn install at the parent level to install ModuleA and ModuleB to your local Maven repository.
Related
I am working on a multi-module maven project and have third party jar which isn't available in central or public repository, I also even don't want to place on public repo. I am providing following plugin directive in my parent pom to install jar in my local maven repository before its dependency is resolved in child project.
Now I provide dependency in child project as;
But I build the project, it successfully adds dependency in local maven repository (places third party jar in .m2 folder) but the at the same time it gives following error. Looks like, it searches this jar file in child projects libs folder as well, while I have already placed it on root (in myproject.parent/libs).
Failed to execute goal org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install-file (install-
external-non-maven1-jar) on project myProject.core: The specified file 'C:\Users\myuser\git\MyProjectRepository\myproject.parent\myproject.core\libs\be-ixf-java-sdk-jar-with-dependencies.jar' not exists.
I already know scope and systemPath option but I don't want to use it for some reason.
Kindly help in identifying what I am missing ?
The best approach that you could have if your project have a centralized maven repo like nexus setup is to have your third party library also added to the repo. Now , you are having the bin file added to your project and it's not preferable.
If you already have the required jar under your project code in like : libs\*, then why can't you refer the dependency directly in your pom.xml instead of having to install it in your local maven repo and then use it .
<dependency>
<groupId>anything</groupId>
<artifactId>anything</artifactId>
<version>anything</version>
<scope>system</scope>
<systemPath>${basedir}/lib/jar_name.jar</systemPath>
</dependency>
providing the location of the dependency in your project directory should resolve it during build itself.Look at Maven System dependencies.
Since you do not want to change your current setup . Please bear in mind the following about maven pom structure :
Project Aggregation is similar to Project Inheritance. But instead of
specifying the parent POM from the module, it specifies the modules
from the parent POM. By doing so, the parent project now knows its
modules, and if a Maven command is invoked against the parent project,
that Maven command will then be executed to the parent's modules as
well
So the maven-install-plugin execution that you added in main pom.xml might be getting triggered for all your modules because of this reason. You might want to move that to the module that you actually need this lib to be included in.Read maven doc.
Related : force Maven to copy dependencies into target/lib
I've googled and stack-overflowed everything, but maybe not enough as I'm still not clear how one adds a module of a Maven project as a dependency in another.
So for example let's say we've got:
MajorPager
|___ POM.xml
|___ chuck-commons-core
| |____POM.xml
|____rajni-commons-core
|____POM.xml
Now I want to add chuck-commons-core but not rajni-commons-core. If I do it directly, it can't find the module. So I ran across the following discussions on stack-overflow and my old friend Guggal:
In summary, the below discussions talk of how to create multi-module projects but not really how to include the sub-modules in a top-level POM into another project.
Useful discussions for context
SO Adding a reference to a parent POM project
SO How to add a parent POM as dependency to a different maven project
SO Adding a reference to Parent POM
SO Maven Parent POM vs Modules POM
SO Depend on multi-module aggregator project
SO How to add dependency in Eclipse?
SO How do I configure Maven multi-module-dependency on sub project with different package?
SO How to add a module in parent projects POM as dependency?
SO How to add a dependency in Maven?
Maven dependency mechanism
Maven POM aggregation
Baeldung Multi-module project
Codetab Maven multi-module
Howtodoinjava Maven parent child POM example
Mastertheboss Maven multi-module tutorial
Codetab Multi-module hierarchical project
Sonatype How to share resources across projects
Spring Multi-module project
Concretely, I'd just like a summary from an expert how they add a sub-module of a Parent POM as a dependency to another project.
As of now, I think this is the best solution - to add the following ccodee to the POM.xml of the MajorPager.
Code block 1 incoming
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.teachme.how</groupId>
<artifactId>MajorPager</artifactId>
<version>0.6-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Code block 2 incoming
<dependencies>
...
<dependency>
<groupId>com.teachme.how</groupId>
<artifactId>norris-commons-core</artifactId>
<version>0.6</version>
</dependency>
...
</dependencies>
When you do so enables Maven to find out where the dependency are - and so Maven picks them up with mvn clean -U install or mvn package -U -DskipTests. And I should like to be educated if this isn't the most effective pattern. Or if any of the fields above are optional that Maven doesn't want me to specify because it can derive it on it's own (say for example, version tag?) - please let me know if that's case as well.
I have a project structure like:
However, whenever I run mvn clean test -DskipTests from the Project 1 directory, it ends up NOT including the Project 2 module in the Maven reactor even though I've listed it as a dependency in Project 1 as follows:
<dependency>
<groupId>com.main.sub</groupId>
<artifactId>project2-artId</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
What could be happening and why isnt the dependency being recognized?
From https://maven.apache.org/guides/mini/guide-multiple-modules.html; the reactor "Collects all the available modules to build". (modules of the project that is currently being built)
You need to: create a parent project, with packaging pom; add two modules to this project (one for Project1, one for Project2), and submodules for project1.
Then, when you build the parent project, the build order for all modules are decided by the reactor-
I am using maven multi module build like below
<modules>
<module>module1</module>
<module>module2</module>// dependant on module 1
<module>module3</module>// dependant on module 2
<module>warApplication</module>// its a war file dependant on above modules
</modules>
Present build behaviour :-
If i make a change only in module 1, maven will build even module2, module3 source files and then put module1,module2,module3 jar files under warApplication/target/lib.
Is there a configuration/way when i trigger the build, maven verifies if any file was modified under the module, if no skip that module. For war file it will put specific
lib file that got modified. This will save a lot of time.
To check if any file got modified under module or not, maven can store last build time . Before starting build it will check if any of the file got modified after last build timestamp, if yes build it otherwise skip it.
Is there any maven plugin available for this ?
Update :-
My project structure is
TopFolder
.mvn directory -> extensions.xml
build directory->build-Projects-> pom.xml
build directory-> parent -> pom.xml
modules - > module1 -> pom.xml
modules - > module2 -> pom.xml
modules - > module3 -> pom.xml
Here is i am including modules in parent pom
<modules>
<module>../../modules/module1</module>
<module>../../modules/module2</module>
</modules>
. I have included scm tag <developerConnection>scm:svn:https://comp.com/svn/trunk</developerConnection> in both below projects
build directory->build-Projects-> pom.xml
build directory-> parent -> pom.xml
Running build from build directory->build-Projects-> pom.xml.
But the issue is when I change any file any module and run build from build directory-> pom.xml, its not detecting module changes ?
Porbably the best option is using incremental module builder. The first time after making changes in your extension file you need to mvn install and so on you can use mvn -b incremental package which just build only the modules which are changed from the previous build. The github address is https://github.com/khmarbaise/incremental-module-builder
You can use profiles to build what you know has change, as timestamp isn't supported within the pom
See here for more details : Maven Modules optional in pom.xml
My project structure (multi module) is like this
parent
projectA
projectB
... other modules
parent also actually has a parent (Spring Boot).
I have set up a Jenkins jobs to compile & test on every commit, so it runs:
mvn -f pom.xml clean install
And that all works fine. ProjectB depends on ProjectA (which is like a common classes type of project) and is a Spring boot application. So the dependency information is the regular:
<dependency>
<groupId>Group</groupId>
<artifactId>ProjectA</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
ProjectB has a separate job in Jenkins to build the deployable jar file and deploy it to server. So the command there is:
mvn -f ProjectB/pom.xml clean install antrun:run
This fails with a message like:
[WARNING] The POM for Group:ProjectB:1.0-SNAPSHOT is missing, no dependency information available
...
[ERROR] Failed to execute goal on project host-api: Could not resolve dependencies for project Group:ProjectB:1.0-SNAPSHOT: The following artifacts could not be resolved: Group:ProjectA:jar:1.0-SNAPSHOT...
Now I can resolve this by doing a mvn install in the ProjectA directory - I've tested this and it does resolve the issue.
But my question is why should I have to? Shouldn't Maven figure out it should be installing the jar in the local repo?
Thanks in advance
TL;DR Tell maven about the structure of your project.
When you run the command
mvn -f pom.xml clean install
Then maven uses the reactor to work out the order of the modules, something like the following is output:
[INFO] Reactor build order:
[INFO] ProjectA
[INFO] ProjectB
So Maven first builds project A, then builds project B.
When you run the command:
mvn -f ProjectB/pom.xml clean install antrun:run
Then you have a problem; maven isn't starting from the parent - it's starting from a child. It's not told about the hierarchy of projects needed to be built first.
If you want to build a single project from a maven multimodule project, along with dependencies you should use:
mvn -f pom.xml -pl ProjectB -am install antrun:run
Where:
-pl ProjectB is the "project list" option, it tells maven to build these specific projects
-am is the "also make" option, it tells maven to build any projects that the projects in pl are dependant on
Specify the dependencies build part when you run the build:
Guide to Working with Multiple Modules
So I suppose the rule is, always build the parent project first and then run goals on subprojects afterwards.
The fix for me was to run clean install on the parent project first and then have a second build configuration in Jenkins that ran -f ProjectB/pom.xml antrun:run